xref: /petsc/src/dm/impls/plex/plexrefine.c (revision ad8374ff2f985bdc2bc92bf983ebfe33d47cf8fc)
1af0996ceSBarry Smith #include <petsc/private/dmpleximpl.h>   /*I      "petscdmplex.h"   I*/
275d3a19aSMatthew G. Knepley #include <petscsf.h>
375d3a19aSMatthew G. Knepley 
475d3a19aSMatthew G. Knepley #undef __FUNCT__
575d3a19aSMatthew G. Knepley #define __FUNCT__ "GetDepthStart_Private"
675d3a19aSMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode GetDepthStart_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cStart, PetscInt *fStart, PetscInt *eStart, PetscInt *vStart)
775d3a19aSMatthew G. Knepley {
875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
975d3a19aSMatthew G. Knepley   if (cStart) *cStart = 0;
1015fa1f8eSMatthew G. Knepley   if (vStart) *vStart = depth < 0 ? 0 : depthSize[depth];
1115fa1f8eSMatthew G. Knepley   if (fStart) *fStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0];
1215fa1f8eSMatthew G. Knepley   if (eStart) *eStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1];
1375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
1475d3a19aSMatthew G. Knepley }
1575d3a19aSMatthew G. Knepley 
1675d3a19aSMatthew G. Knepley #undef __FUNCT__
1775d3a19aSMatthew G. Knepley #define __FUNCT__ "GetDepthEnd_Private"
1875d3a19aSMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode GetDepthEnd_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cEnd, PetscInt *fEnd, PetscInt *eEnd, PetscInt *vEnd)
1975d3a19aSMatthew G. Knepley {
2075d3a19aSMatthew G. Knepley   PetscFunctionBegin;
2115fa1f8eSMatthew G. Knepley   if (cEnd) *cEnd = depth < 0 ? 0 : depthSize[depth];
2215fa1f8eSMatthew G. Knepley   if (vEnd) *vEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0];
2315fa1f8eSMatthew G. Knepley   if (fEnd) *fEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1];
2415fa1f8eSMatthew G. Knepley   if (eEnd) *eEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1] + depthSize[1];
2575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
2675d3a19aSMatthew G. Knepley }
2775d3a19aSMatthew G. Knepley 
2875d3a19aSMatthew G. Knepley #undef __FUNCT__
29bed052eaSMatthew G. Knepley #define __FUNCT__ "CellRefinerGetAffineTransforms_Internal"
30bed052eaSMatthew G. Knepley /* Gets the affine map from the original cell to each subcell */
31bed052eaSMatthew G. Knepley PetscErrorCode CellRefinerGetAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[])
32bed052eaSMatthew G. Knepley {
33bed052eaSMatthew G. Knepley   PetscReal     *v = NULL, *j = NULL, *invj = NULL, detJ;
34bed052eaSMatthew G. Knepley   PetscInt       dim, s;
35bed052eaSMatthew G. Knepley   PetscErrorCode ierr;
36bed052eaSMatthew G. Knepley 
37bed052eaSMatthew G. Knepley   PetscFunctionBegin;
38bed052eaSMatthew G. Knepley   switch (refiner) {
399b1a0e7fSLawrence Mitchell   case REFINER_NOOP: break;
409b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
41260b6d3fSMatthew G. Knepley     /*
42260b6d3fSMatthew G. Knepley      2
43260b6d3fSMatthew G. Knepley      |\
44260b6d3fSMatthew G. Knepley      | \
45260b6d3fSMatthew G. Knepley      |  \
46260b6d3fSMatthew G. Knepley      |   \
47260b6d3fSMatthew G. Knepley      | C  \
48260b6d3fSMatthew G. Knepley      |     \
49260b6d3fSMatthew G. Knepley      |      \
50260b6d3fSMatthew G. Knepley      2---1---1
51260b6d3fSMatthew G. Knepley      |\  D  / \
52260b6d3fSMatthew G. Knepley      | 2   0   \
53260b6d3fSMatthew G. Knepley      |A \ /  B  \
54260b6d3fSMatthew G. Knepley      0---0-------1
55260b6d3fSMatthew G. Knepley      */
56bed052eaSMatthew G. Knepley     dim = 2;
57bed052eaSMatthew G. Knepley     if (numSubcells) *numSubcells = 4;
58bed052eaSMatthew G. Knepley     if (v0) {
59bed052eaSMatthew G. Knepley       ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr);
60bed052eaSMatthew G. Knepley       /* A */
61bed052eaSMatthew G. Knepley       v[0+0] = -1.0; v[0+1] = -1.0;
62bed052eaSMatthew G. Knepley       j[0+0] =  0.5; j[0+1] =  0.0;
63bed052eaSMatthew G. Knepley       j[0+2] =  0.0; j[0+3] =  0.5;
64bed052eaSMatthew G. Knepley       /* B */
65bed052eaSMatthew G. Knepley       v[2+0] =  0.0; v[2+1] = -1.0;
66bed052eaSMatthew G. Knepley       j[4+0] =  0.5; j[4+1] =  0.0;
67bed052eaSMatthew G. Knepley       j[4+2] =  0.0; j[4+3] =  0.5;
68bed052eaSMatthew G. Knepley       /* C */
69bed052eaSMatthew G. Knepley       v[4+0] = -1.0; v[4+1] =  0.0;
70bed052eaSMatthew G. Knepley       j[8+0] =  0.5; j[8+1] =  0.0;
71bed052eaSMatthew G. Knepley       j[8+2] =  0.0; j[8+3] =  0.5;
72bed052eaSMatthew G. Knepley       /* D */
73bed052eaSMatthew G. Knepley       v[6+0]  =  0.0; v[6+1]  = -1.0;
74bed052eaSMatthew G. Knepley       j[12+0] =  0.0; j[12+1] = -0.5;
75bed052eaSMatthew G. Knepley       j[12+2] =  0.5; j[12+3] =  0.5;
76bed052eaSMatthew G. Knepley       for (s = 0; s < 4; ++s) {
77bed052eaSMatthew G. Knepley         DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]);
78bed052eaSMatthew G. Knepley         DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ);
79bed052eaSMatthew G. Knepley       }
80bed052eaSMatthew G. Knepley     }
81bed052eaSMatthew G. Knepley     break;
829b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
83260b6d3fSMatthew G. Knepley     /*
84260b6d3fSMatthew G. Knepley      3---------2---------2
85260b6d3fSMatthew G. Knepley      |         |         |
86260b6d3fSMatthew G. Knepley      |    D    2    C    |
87260b6d3fSMatthew G. Knepley      |         |         |
88260b6d3fSMatthew G. Knepley      3----3----0----1----1
89260b6d3fSMatthew G. Knepley      |         |         |
90260b6d3fSMatthew G. Knepley      |    A    0    B    |
91260b6d3fSMatthew G. Knepley      |         |         |
92260b6d3fSMatthew G. Knepley      0---------0---------1
93260b6d3fSMatthew G. Knepley      */
94260b6d3fSMatthew G. Knepley     dim = 2;
95260b6d3fSMatthew G. Knepley     if (numSubcells) *numSubcells = 4;
96260b6d3fSMatthew G. Knepley     if (v0) {
97260b6d3fSMatthew G. Knepley       ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr);
98260b6d3fSMatthew G. Knepley       /* A */
99260b6d3fSMatthew G. Knepley       v[0+0] = -1.0; v[0+1] = -1.0;
100260b6d3fSMatthew G. Knepley       j[0+0] =  0.5; j[0+1] =  0.0;
101260b6d3fSMatthew G. Knepley       j[0+2] =  0.0; j[0+3] =  0.5;
102260b6d3fSMatthew G. Knepley       /* B */
103260b6d3fSMatthew G. Knepley       v[2+0] =  0.0; v[2+1] = -1.0;
104260b6d3fSMatthew G. Knepley       j[4+0] =  0.5; j[4+1] =  0.0;
105260b6d3fSMatthew G. Knepley       j[4+2] =  0.0; j[4+3] =  0.5;
106260b6d3fSMatthew G. Knepley       /* C */
107260b6d3fSMatthew G. Knepley       v[4+0] =  0.0; v[4+1] =  0.0;
108260b6d3fSMatthew G. Knepley       j[8+0] =  0.5; j[8+1] =  0.0;
109260b6d3fSMatthew G. Knepley       j[8+2] =  0.0; j[8+3] =  0.5;
110260b6d3fSMatthew G. Knepley       /* D */
111260b6d3fSMatthew G. Knepley       v[6+0]  = -1.0; v[6+1]  =  0.0;
112260b6d3fSMatthew G. Knepley       j[12+0] =  0.5; j[12+1] =  0.0;
113260b6d3fSMatthew G. Knepley       j[12+2] =  0.0; j[12+3] =  0.5;
114260b6d3fSMatthew G. Knepley       for (s = 0; s < 4; ++s) {
115260b6d3fSMatthew G. Knepley         DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]);
116260b6d3fSMatthew G. Knepley         DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ);
117260b6d3fSMatthew G. Knepley       }
118260b6d3fSMatthew G. Knepley     }
119260b6d3fSMatthew G. Knepley     break;
120bed052eaSMatthew G. Knepley   default:
121bed052eaSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
122bed052eaSMatthew G. Knepley   }
123bed052eaSMatthew G. Knepley   if (v0) {*v0 = v; *jac = j; *invjac = invj;}
124bed052eaSMatthew G. Knepley   PetscFunctionReturn(0);
125bed052eaSMatthew G. Knepley }
126bed052eaSMatthew G. Knepley 
127bed052eaSMatthew G. Knepley #undef __FUNCT__
128bed052eaSMatthew G. Knepley #define __FUNCT__ "CellRefinerRestoreAffineTransforms_Internal"
129bed052eaSMatthew G. Knepley PetscErrorCode CellRefinerRestoreAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[])
130bed052eaSMatthew G. Knepley {
131bed052eaSMatthew G. Knepley   PetscErrorCode ierr;
132bed052eaSMatthew G. Knepley 
133bed052eaSMatthew G. Knepley   PetscFunctionBegin;
134bed052eaSMatthew G. Knepley   ierr = PetscFree3(*v0,*jac,*invjac);CHKERRQ(ierr);
135bed052eaSMatthew G. Knepley   PetscFunctionReturn(0);
136bed052eaSMatthew G. Knepley }
137bed052eaSMatthew G. Knepley 
138bed052eaSMatthew G. Knepley #undef __FUNCT__
13980389061SMatthew G. Knepley #define __FUNCT__ "CellRefinerInCellTest_Internal"
14080389061SMatthew G. Knepley /* Should this be here or in the DualSpace somehow? */
14180389061SMatthew G. Knepley PetscErrorCode CellRefinerInCellTest_Internal(CellRefiner refiner, const PetscReal point[], PetscBool *inside)
14280389061SMatthew G. Knepley {
14380389061SMatthew G. Knepley   PetscReal sum = 0.0;
14480389061SMatthew G. Knepley   PetscInt  d;
14580389061SMatthew G. Knepley 
14680389061SMatthew G. Knepley   PetscFunctionBegin;
14780389061SMatthew G. Knepley   *inside = PETSC_TRUE;
14880389061SMatthew G. Knepley   switch (refiner) {
1499b1a0e7fSLawrence Mitchell   case REFINER_NOOP: break;
1506c0c04f5SMatthew G. Knepley   case REFINER_SIMPLEX_2D:
15180389061SMatthew G. Knepley     for (d = 0; d < 2; ++d) {
15280389061SMatthew G. Knepley       if (point[d] < -1.0) {*inside = PETSC_FALSE; break;}
15380389061SMatthew G. Knepley       sum += point[d];
15480389061SMatthew G. Knepley     }
15580389061SMatthew G. Knepley     if (sum > 0.0) {*inside = PETSC_FALSE; break;}
15680389061SMatthew G. Knepley     break;
1576c0c04f5SMatthew G. Knepley   case REFINER_HEX_2D:
15880389061SMatthew G. Knepley     for (d = 0; d < 2; ++d) if ((point[d] < -1.0) || (point[d] > 1.0)) {*inside = PETSC_FALSE; break;}
15980389061SMatthew G. Knepley     break;
16080389061SMatthew G. Knepley   default:
16180389061SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
16280389061SMatthew G. Knepley   }
16380389061SMatthew G. Knepley   PetscFunctionReturn(0);
16480389061SMatthew G. Knepley }
16580389061SMatthew G. Knepley 
16680389061SMatthew G. Knepley #undef __FUNCT__
16775d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerGetSizes"
16886150812SJed Brown static PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[])
16975d3a19aSMatthew G. Knepley {
1706ce3c06aSMatthew G. Knepley   PetscInt       cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax;
17175d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
17275d3a19aSMatthew G. Knepley 
17375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
17475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
17575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
17675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
17775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
17875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
17975d3a19aSMatthew G. Knepley   switch (refiner) {
1809b1a0e7fSLawrence Mitchell   case REFINER_NOOP:
1813478d7aaSMatthew G. Knepley     break;
1820314a74cSLawrence Mitchell   case REFINER_SIMPLEX_1D:
1830314a74cSLawrence Mitchell     depthSize[0] = vEnd - vStart + cEnd - cStart;         /* Add a vertex on every cell. */
1840314a74cSLawrence Mitchell     depthSize[1] = 2*(cEnd - cStart);                     /* Split every cell in 2. */
1850314a74cSLawrence Mitchell     break;
1869b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
18775d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fEnd - fStart;         /* Add a vertex on every face */
18875d3a19aSMatthew 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 */
18975d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cEnd - cStart);                     /* Every cell split into 4 cells */
19075d3a19aSMatthew G. Knepley     break;
1919b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
19275d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
19375d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
19475d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fMax - fStart;                                         /* Add a vertex on every face, but not hybrid faces */
19575d3a19aSMatthew 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 */
19675d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax);                                   /* Interior cells split into 4 cells, Hybrid cells split into 2 cells */
19775d3a19aSMatthew G. Knepley     break;
1989b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
199149f48fdSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */
20075d3a19aSMatthew 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 */
20175d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cEnd - cStart);                             /* Every cell split into 4 cells */
20275d3a19aSMatthew G. Knepley     break;
2039b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
204a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
205a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
206a97b51b8SMatthew G. Knepley     /* Quadrilateral */
207a97b51b8SMatthew G. Knepley     depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart;                 /* Add a vertex on every face and cell */
208a97b51b8SMatthew G. Knepley     depthSize[1] = 2*(fMax - fStart) + 4*(cMax - cStart);                         /* Every face is split into 2 faces, and 4 faces are added for each cell */
209a97b51b8SMatthew G. Knepley     depthSize[2] = 4*(cMax - cStart);                                             /* Every cell split into 4 cells */
210a97b51b8SMatthew G. Knepley     /* Segment Prisms */
211a97b51b8SMatthew G. Knepley     depthSize[0] += 0;                                                            /* No hybrid vertices */
212a97b51b8SMatthew G. Knepley     depthSize[1] +=   (fEnd - fMax)  +   (cEnd - cMax);                           /* Every hybrid face remains and 1 faces is added for each hybrid cell */
213a97b51b8SMatthew G. Knepley     depthSize[2] += 2*(cEnd - cMax);                                              /* Every hybrid cell split into 2 cells */
214a97b51b8SMatthew G. Knepley     break;
2159b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
216b5da9499SMatthew G. Knepley     depthSize[0] =    vEnd - vStart  +    eEnd - eStart;                    /* Add a vertex on every edge */
217b5da9499SMatthew 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 */
218b5da9499SMatthew G. Knepley     depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart);                   /* Every face split into 4 faces and 8 faces are added for each cell */
219b5da9499SMatthew G. Knepley     depthSize[3] = 8*(cEnd - cStart);                                       /* Every cell split into 8 cells */
220b5da9499SMatthew G. Knepley     break;
2219b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
222b5da9499SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
2236ce3c06aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
224b5da9499SMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
225dae4404aSMatthew G. Knepley     /* Tetrahedra */
226dae4404aSMatthew G. Knepley     depthSize[0]  =    vEnd - vStart  +    eMax - eStart;                    /* Add a vertex on every interior edge */
227dae4404aSMatthew 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 */
228dae4404aSMatthew G. Knepley     depthSize[2]  = 4*(fMax - fStart) + 8*(cMax - cStart);                   /* Every interior face split into 4 faces, 8 faces added for each interior cell */
229dae4404aSMatthew G. Knepley     depthSize[3]  = 8*(cMax - cStart);                                       /* Every interior cell split into 8 cells */
230dae4404aSMatthew G. Knepley     /* Triangular Prisms */
231dae4404aSMatthew G. Knepley     depthSize[0] += 0;                                                       /* No hybrid vertices */
232dae4404aSMatthew G. Knepley     depthSize[1] +=   (eEnd - eMax)   +   (fEnd - fMax);                     /* Every hybrid edge remains, 1 edge for every hybrid face */
2336ce3c06aSMatthew 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 */
234dae4404aSMatthew G. Knepley     depthSize[3] += 4*(cEnd - cMax);                                         /* Every hybrid cell split into 4 cells */
235b5da9499SMatthew G. Knepley     break;
2369b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
2376ce3c06aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */
2386ce3c06aSMatthew 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 */
2396ce3c06aSMatthew 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 */
2406ce3c06aSMatthew G. Knepley     depthSize[3] = 8*(cEnd - cStart);                                             /* Every cell split into 8 cells */
2416ce3c06aSMatthew G. Knepley     break;
2429b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
24327fcede3SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
24427fcede3SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
24527fcede3SMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
24627fcede3SMatthew G. Knepley     /* Hexahedra */
24727fcede3SMatthew G. Knepley     depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */
24827fcede3SMatthew 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 */
24927fcede3SMatthew 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 */
25027fcede3SMatthew G. Knepley     depthSize[3] = 8*(cMax - cStart);                                             /* Every cell split into 8 cells */
25127fcede3SMatthew G. Knepley     /* Quadrilateral Prisms */
25227fcede3SMatthew G. Knepley     depthSize[0] += 0;                                                            /* No hybrid vertices */
25327fcede3SMatthew G. Knepley     depthSize[1] +=   (eEnd - eMax)   +   (fEnd - fMax)   +   (cEnd - cMax);      /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */
25427fcede3SMatthew 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 */
25527fcede3SMatthew G. Knepley     depthSize[3] += 4*(cEnd - cMax);                                              /* Every hybrid cell split into 4 cells */
25627fcede3SMatthew G. Knepley     break;
25775d3a19aSMatthew G. Knepley   default:
25875d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
25975d3a19aSMatthew G. Knepley   }
26075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
26175d3a19aSMatthew G. Knepley }
26275d3a19aSMatthew G. Knepley 
26342525629SMatthew G. Knepley /* Return triangle edge for orientation o, if it is r for o == 0 */
26442525629SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) {
265518a8359SMatthew G. Knepley   return (o < 0 ? 2-(o+r) : o+r)%3;
266518a8359SMatthew G. Knepley }
267de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) {
268de65f515SMatthew G. Knepley   return (o < 0 ? 2-(o+s) : 3+s-o)%3;
269de65f515SMatthew G. Knepley }
270518a8359SMatthew G. Knepley 
271518a8359SMatthew G. Knepley /* Return triangle subface for orientation o, if it is r for o == 0 */
272518a8359SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) {
2734bae88c7SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%3;
27442525629SMatthew G. Knepley }
275de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) {
276de65f515SMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 3+s-o)%3;
277de65f515SMatthew G. Knepley }
27842525629SMatthew G. Knepley 
279431647a4SMatthew G. Knepley /* I HAVE NO IDEA: Return ??? for orientation o, if it is r for o == 0 */
280431647a4SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTetSomething_Static(PetscInt o, PetscInt r) {
281431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+r) : o+r)%3;
282431647a4SMatthew G. Knepley }
283431647a4SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTetSomethingInverse_Static(PetscInt o, PetscInt s) {
284431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+s) : 3+s-o)%3;
285431647a4SMatthew G. Knepley }
286431647a4SMatthew G. Knepley 
28742525629SMatthew G. Knepley 
288e3f8b1d6SMatthew G. Knepley /* Return quad edge for orientation o, if it is r for o == 0 */
289e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) {
290e3f8b1d6SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%4;
291e3f8b1d6SMatthew G. Knepley }
292d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) {
293d6d937efSMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 4+s-o)%4;
294d6d937efSMatthew G. Knepley }
295e3f8b1d6SMatthew G. Knepley 
296e3f8b1d6SMatthew G. Knepley /* Return quad subface for orientation o, if it is r for o == 0 */
297e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) {
2984bae88c7SMatthew G. Knepley   return (o < 0 ? 4-(o+r) : o+r)%4;
29942525629SMatthew G. Knepley }
300d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) {
301d6d937efSMatthew G. Knepley   return (o < 0 ? 4-(o+s) : 4+s-o)%4;
302d6d937efSMatthew G. Knepley }
30342525629SMatthew G. Knepley 
30475d3a19aSMatthew G. Knepley #undef __FUNCT__
30575d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetConeSizes"
30686150812SJed Brown static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
30775d3a19aSMatthew G. Knepley {
308b5da9499SMatthew 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;
30975d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
31075d3a19aSMatthew G. Knepley 
31175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
3122a5d0125SJed Brown   if (!refiner) PetscFunctionReturn(0);
31375d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
31475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
31575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
31675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
31775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
31875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
3192a5d0125SJed Brown   ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
32075d3a19aSMatthew G. Knepley   switch (refiner) {
3210314a74cSLawrence Mitchell   case REFINER_SIMPLEX_1D:
3220314a74cSLawrence Mitchell     /* All cells have 2 vertices */
3230314a74cSLawrence Mitchell     for (c = cStart; c < cEnd; ++c) {
3240314a74cSLawrence Mitchell       for (r = 0; r < 2; ++r) {
3250314a74cSLawrence Mitchell         const PetscInt newp = cStartNew + (c - cStart)*2 + r;
3260314a74cSLawrence Mitchell 
3270314a74cSLawrence Mitchell         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
3280314a74cSLawrence Mitchell       }
3290314a74cSLawrence Mitchell     }
3300314a74cSLawrence Mitchell     /* Old vertices have identical supports */
3310314a74cSLawrence Mitchell     for (v = vStart; v < vEnd; ++v) {
3320314a74cSLawrence Mitchell       const PetscInt newp = vStartNew + (v - vStart);
3330314a74cSLawrence Mitchell       PetscInt       size;
3340314a74cSLawrence Mitchell 
3350314a74cSLawrence Mitchell       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
3360314a74cSLawrence Mitchell       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
3370314a74cSLawrence Mitchell     }
3380314a74cSLawrence Mitchell     /* Cell vertices have support 2 */
3390314a74cSLawrence Mitchell     for (c = cStart; c < cEnd; ++c) {
3400314a74cSLawrence Mitchell       const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart);
3410314a74cSLawrence Mitchell 
3420314a74cSLawrence Mitchell       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
3430314a74cSLawrence Mitchell     }
3440314a74cSLawrence Mitchell     break;
3459b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
34675d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
34775d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
34875d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
34975d3a19aSMatthew G. Knepley         const PetscInt newp = (c - cStart)*4 + r;
35075d3a19aSMatthew G. Knepley 
35175d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
35275d3a19aSMatthew G. Knepley       }
35375d3a19aSMatthew G. Knepley     }
35475d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
35575d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
35675d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
35775d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
35875d3a19aSMatthew G. Knepley         PetscInt       size;
35975d3a19aSMatthew G. Knepley 
36075d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
36175d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
36275d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
36375d3a19aSMatthew G. Knepley       }
36475d3a19aSMatthew G. Knepley     }
36575d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
36675d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
36775d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
36875d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
36975d3a19aSMatthew G. Knepley 
37075d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
37175d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
37275d3a19aSMatthew G. Knepley       }
37375d3a19aSMatthew G. Knepley     }
37475d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
37575d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
37675d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
37775d3a19aSMatthew G. Knepley       PetscInt       size;
37875d3a19aSMatthew G. Knepley 
37975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
38075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
38175d3a19aSMatthew G. Knepley     }
38275d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
38375d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
38475d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
38575d3a19aSMatthew G. Knepley       PetscInt       size;
38675d3a19aSMatthew G. Knepley 
38775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
38875d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr);
38975d3a19aSMatthew G. Knepley     }
39075d3a19aSMatthew G. Knepley     break;
3919b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
39275d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
39375d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
39475d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
395149f48fdSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
39675d3a19aSMatthew G. Knepley 
39775d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
39875d3a19aSMatthew G. Knepley       }
39975d3a19aSMatthew G. Knepley     }
40075d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
40175d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
40275d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
40375d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
40475d3a19aSMatthew G. Knepley         PetscInt       size;
40575d3a19aSMatthew G. Knepley 
40675d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
40775d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
40875d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
40975d3a19aSMatthew G. Knepley       }
41075d3a19aSMatthew G. Knepley     }
41175d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
41275d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
41375d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
41475d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
41575d3a19aSMatthew G. Knepley 
41675d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
41775d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
41875d3a19aSMatthew G. Knepley       }
41975d3a19aSMatthew G. Knepley     }
42075d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
42175d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
42275d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
42375d3a19aSMatthew G. Knepley       PetscInt       size;
42475d3a19aSMatthew G. Knepley 
42575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
42675d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
42775d3a19aSMatthew G. Knepley     }
42875d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
42975d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
43075d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
43175d3a19aSMatthew G. Knepley       PetscInt       size;
43275d3a19aSMatthew G. Knepley 
43375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
43475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
43575d3a19aSMatthew G. Knepley     }
43675d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
43775d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
43875d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
43975d3a19aSMatthew G. Knepley 
44075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
44175d3a19aSMatthew G. Knepley     }
44275d3a19aSMatthew G. Knepley     break;
4439b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
44475d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
44575d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
44675d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
44775d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
44875d3a19aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
44975d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
45075d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
45175d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
45275d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
45375d3a19aSMatthew G. Knepley 
45475d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
45575d3a19aSMatthew G. Knepley       }
45675d3a19aSMatthew G. Knepley     }
45775d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
45875d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
45975d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
46075d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
46175d3a19aSMatthew G. Knepley 
46275d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
46375d3a19aSMatthew G. Knepley       }
46475d3a19aSMatthew G. Knepley     }
46575d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
46675d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
46775d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
46875d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
46975d3a19aSMatthew G. Knepley         PetscInt       size;
47075d3a19aSMatthew G. Knepley 
47175d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
47275d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
47375d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
47475d3a19aSMatthew G. Knepley       }
47575d3a19aSMatthew G. Knepley     }
47675d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
47775d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
47875d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
47975d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
48075d3a19aSMatthew G. Knepley 
48175d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
48275d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
48375d3a19aSMatthew G. Knepley       }
48475d3a19aSMatthew G. Knepley     }
48575d3a19aSMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
48675d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
48775d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
48875d3a19aSMatthew G. Knepley       PetscInt       size;
48975d3a19aSMatthew G. Knepley 
49075d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
49175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
49275d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
49375d3a19aSMatthew G. Knepley     }
49475d3a19aSMatthew G. Knepley     /* Hybrid cell faces have 2 vertices and 2 cells */
49575d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
49675d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
49775d3a19aSMatthew G. Knepley 
49875d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
49975d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
50075d3a19aSMatthew G. Knepley     }
50175d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
50275d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
50375d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
50475d3a19aSMatthew G. Knepley       PetscInt       size;
50575d3a19aSMatthew G. Knepley 
50675d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
50775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
50875d3a19aSMatthew G. Knepley     }
50975d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
51075d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
51175d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
51275d3a19aSMatthew G. Knepley       const PetscInt *support;
51375d3a19aSMatthew G. Knepley       PetscInt       size, newSize = 2, s;
51475d3a19aSMatthew G. Knepley 
51575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
51675d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
51775d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
51875d3a19aSMatthew G. Knepley         if (support[s] >= cMax) newSize += 1;
51975d3a19aSMatthew G. Knepley         else newSize += 2;
52075d3a19aSMatthew G. Knepley       }
52175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr);
52275d3a19aSMatthew G. Knepley     }
52375d3a19aSMatthew G. Knepley     break;
5249b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
525a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
526a97b51b8SMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
527a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
528a97b51b8SMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
529a97b51b8SMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
530a97b51b8SMatthew G. Knepley     /* Interior cells have 4 faces */
531a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
532a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
533a97b51b8SMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
534a97b51b8SMatthew G. Knepley 
535a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
536a97b51b8SMatthew G. Knepley       }
537a97b51b8SMatthew G. Knepley     }
538a97b51b8SMatthew G. Knepley     /* Hybrid cells have 4 faces */
539a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
540a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
541a97b51b8SMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
542a97b51b8SMatthew G. Knepley 
543a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
544a97b51b8SMatthew G. Knepley       }
545a97b51b8SMatthew G. Knepley     }
546a97b51b8SMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
547a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
548a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
549a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
550a97b51b8SMatthew G. Knepley         PetscInt       size;
551a97b51b8SMatthew G. Knepley 
552a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
553a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
554a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
555a97b51b8SMatthew G. Knepley       }
556a97b51b8SMatthew G. Knepley     }
557a97b51b8SMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
558a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
559a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
560a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
561a97b51b8SMatthew G. Knepley 
562a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
563a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
564a97b51b8SMatthew G. Knepley       }
565a97b51b8SMatthew G. Knepley     }
566a97b51b8SMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
567a97b51b8SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
568a97b51b8SMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
569a97b51b8SMatthew G. Knepley       PetscInt       size;
570a97b51b8SMatthew G. Knepley 
571a97b51b8SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
572a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
573a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
574a97b51b8SMatthew G. Knepley     }
575a97b51b8SMatthew G. Knepley     /* Hybrid cell faces have 2 vertices and 2 cells */
576a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
577a97b51b8SMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
578a97b51b8SMatthew G. Knepley 
579a97b51b8SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
580a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
581a97b51b8SMatthew G. Knepley     }
582a97b51b8SMatthew G. Knepley     /* Old vertices have identical supports */
583a97b51b8SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
584a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
585a97b51b8SMatthew G. Knepley       PetscInt       size;
586a97b51b8SMatthew G. Knepley 
587a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
588a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
589a97b51b8SMatthew G. Knepley     }
590a97b51b8SMatthew G. Knepley     /* Face vertices have 2 + cells supports */
591a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
592a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
593a97b51b8SMatthew G. Knepley       PetscInt       size;
594a97b51b8SMatthew G. Knepley 
595a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
596a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
597a97b51b8SMatthew G. Knepley     }
598a97b51b8SMatthew G. Knepley     /* Cell vertices have 4 supports */
599a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
600a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
601a97b51b8SMatthew G. Knepley 
602a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
603a97b51b8SMatthew G. Knepley     }
604a97b51b8SMatthew G. Knepley     break;
6059b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
606b5da9499SMatthew G. Knepley     /* All cells have 4 faces */
607b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
608b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
609dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
610b5da9499SMatthew G. Knepley 
611b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
612b5da9499SMatthew G. Knepley       }
613b5da9499SMatthew G. Knepley     }
614b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
615b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
616b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
617b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
618b5da9499SMatthew G. Knepley         PetscInt       size;
619b5da9499SMatthew G. Knepley 
620b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
621b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
622b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
623b5da9499SMatthew G. Knepley       }
624b5da9499SMatthew G. Knepley     }
6259ddff745SMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
626b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
627b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
628b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r;
629b5da9499SMatthew G. Knepley 
630b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
631b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
632b5da9499SMatthew G. Knepley       }
633b5da9499SMatthew G. Knepley     }
634b5da9499SMatthew G. Knepley     /* Split edges have 2 vertices and the same faces */
635b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
636b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
637b5da9499SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
638b5da9499SMatthew G. Knepley         PetscInt       size;
639b5da9499SMatthew G. Knepley 
640b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
641b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
642b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
643b5da9499SMatthew G. Knepley       }
644b5da9499SMatthew G. Knepley     }
645b5da9499SMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
646b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
647b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
648b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
649b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
650b5da9499SMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
651b5da9499SMatthew G. Knepley 
652b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
653b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
654b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
655b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
656b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
657b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
658b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
659b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
66086f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
6619ddff745SMatthew G. Knepley           er = GetTetSomethingInverse_Static(ornt[c], r);
662b5da9499SMatthew G. Knepley           if (er == eint[c]) {
663b5da9499SMatthew G. Knepley             intFaces += 1;
664b5da9499SMatthew G. Knepley           } else {
665b5da9499SMatthew G. Knepley             intFaces += 2;
666b5da9499SMatthew G. Knepley           }
667b5da9499SMatthew G. Knepley         }
668b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
669b5da9499SMatthew G. Knepley       }
670b5da9499SMatthew G. Knepley     }
6719ddff745SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
672b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
673b5da9499SMatthew G. Knepley       const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
674b5da9499SMatthew G. Knepley 
675b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
676b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
677b5da9499SMatthew G. Knepley     }
678b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
679b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
680b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
681b5da9499SMatthew G. Knepley       PetscInt       size;
682b5da9499SMatthew G. Knepley 
683b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
684b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
685b5da9499SMatthew G. Knepley     }
686b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + faces*2 + cells*0/1 supports */
687b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
688b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
689b5da9499SMatthew G. Knepley       PetscInt       size, *star = NULL, starSize, s, cellSize = 0;
690b5da9499SMatthew G. Knepley 
691b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
692b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
693b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
694b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
695b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
696b5da9499SMatthew G. Knepley 
697b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
698b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
699b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
700b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
701b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
70242525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
703b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
704b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
705b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
70642525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
70742525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
708b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
709b5da9499SMatthew G. Knepley         }
710b5da9499SMatthew G. Knepley       }
711b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
712b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr);
713b5da9499SMatthew G. Knepley     }
714b5da9499SMatthew G. Knepley     break;
7159b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
7166ce3c06aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart),
7176ce3c06aSMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
718dae4404aSMatthew G. Knepley     /* Interior cells have 4 faces */
719dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
720dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
721dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
722dae4404aSMatthew G. Knepley 
723dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
724dae4404aSMatthew G. Knepley       }
725dae4404aSMatthew G. Knepley     }
726dae4404aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
727dae4404aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
728dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
729dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
730dae4404aSMatthew G. Knepley 
731dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr);
732dae4404aSMatthew G. Knepley       }
733dae4404aSMatthew G. Knepley     }
7346ce3c06aSMatthew G. Knepley     /* Interior split faces have 3 edges and the same cells as the parent */
735dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
736dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
737dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
738dae4404aSMatthew G. Knepley         PetscInt       size;
739dae4404aSMatthew G. Knepley 
740dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
741dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
742dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
743dae4404aSMatthew G. Knepley       }
744dae4404aSMatthew G. Knepley     }
745dae4404aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
746dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
747dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
748dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r;
749dae4404aSMatthew G. Knepley 
750dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
751dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
752dae4404aSMatthew G. Knepley       }
753dae4404aSMatthew G. Knepley     }
7546ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
7556ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
7566ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
7576ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
7586ce3c06aSMatthew G. Knepley         PetscInt       size;
7596ce3c06aSMatthew G. Knepley 
7606ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
7616ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
7626ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
7636ce3c06aSMatthew G. Knepley       }
7646ce3c06aSMatthew G. Knepley     }
7656ce3c06aSMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
7666ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
7676ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
7686ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r;
7696ce3c06aSMatthew G. Knepley 
7706ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
7716ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
7726ce3c06aSMatthew G. Knepley       }
7736ce3c06aSMatthew G. Knepley     }
7746ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces */
775dae4404aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
776dae4404aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
777dae4404aSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
778dae4404aSMatthew G. Knepley         PetscInt       size;
779dae4404aSMatthew G. Knepley 
780dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
781dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
782dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
783dae4404aSMatthew G. Knepley       }
784dae4404aSMatthew G. Knepley     }
7856ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
786dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
787dae4404aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
788dae4404aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
789dae4404aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
790dae4404aSMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
791dae4404aSMatthew G. Knepley 
792dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
793dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
794dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
795dae4404aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
796dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
797dae4404aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
798dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
799dae4404aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
8006ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
801dae4404aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
8029ddff745SMatthew G. Knepley             er = GetTetSomethingInverse_Static(ornt[c], r);
803dae4404aSMatthew G. Knepley             if (er == eint[c]) {
804dae4404aSMatthew G. Knepley               intFaces += 1;
805dae4404aSMatthew G. Knepley             } else {
806dae4404aSMatthew G. Knepley               intFaces += 2;
807dae4404aSMatthew G. Knepley             }
8086ce3c06aSMatthew G. Knepley           } else {
8096ce3c06aSMatthew G. Knepley             intFaces += 1;
8106ce3c06aSMatthew G. Knepley           }
811dae4404aSMatthew G. Knepley         }
812dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
813dae4404aSMatthew G. Knepley       }
814dae4404aSMatthew G. Knepley     }
8156ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
816dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
817dae4404aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
818dae4404aSMatthew G. Knepley 
819dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
820dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
821dae4404aSMatthew G. Knepley     }
8226ce3c06aSMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
823dae4404aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
8246ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
8256ce3c06aSMatthew G. Knepley       PetscInt       size;
8266ce3c06aSMatthew G. Knepley 
8276ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
8286ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
8296ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
8306ce3c06aSMatthew G. Knepley     }
8316ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
8326ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
8336ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
834dae4404aSMatthew G. Knepley       PetscInt       size;
835dae4404aSMatthew G. Knepley 
836dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
837dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
8386ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr);
839dae4404aSMatthew G. Knepley     }
8406ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
841dae4404aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
842dae4404aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
843dae4404aSMatthew G. Knepley       PetscInt       size;
844dae4404aSMatthew G. Knepley 
845dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
846dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
847dae4404aSMatthew G. Knepley     }
8486ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
8496ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
8506ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
851dae4404aSMatthew G. Knepley       const PetscInt *support;
8526ce3c06aSMatthew G. Knepley       PetscInt        size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0;
853dae4404aSMatthew G. Knepley 
8546ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
8556ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
856dae4404aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
8576ce3c06aSMatthew G. Knepley         if (support[s] < fMax) faceSize += 2;
8586ce3c06aSMatthew G. Knepley         else                   faceSize += 1;
859dae4404aSMatthew G. Knepley       }
8606ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
8616ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
8626ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
8636ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
8646ce3c06aSMatthew G. Knepley 
8656ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
8666ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
8676ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
8686ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
8696ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
8706ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
8716ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
8726ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
8736ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
8746ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
8756ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
8766ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
8776ce3c06aSMatthew G. Knepley         }
8786ce3c06aSMatthew G. Knepley       }
8796ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
8806ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr);
881dae4404aSMatthew G. Knepley     }
882dae4404aSMatthew G. Knepley     break;
8839b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
8842eabf88fSMatthew G. Knepley     /* All cells have 6 faces */
8852eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
8862eabf88fSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
8872eabf88fSMatthew G. Knepley         const PetscInt newp = (c - cStart)*8 + r;
8882eabf88fSMatthew G. Knepley 
8892eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
8902eabf88fSMatthew G. Knepley       }
8912eabf88fSMatthew G. Knepley     }
8922eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
8932eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
8942eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
8952eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
8962eabf88fSMatthew G. Knepley         PetscInt       size;
8972eabf88fSMatthew G. Knepley 
8982eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
8992eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
9002eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
9012eabf88fSMatthew G. Knepley       }
9022eabf88fSMatthew G. Knepley     }
9032eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
9042eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
9052eabf88fSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
9062eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
9072eabf88fSMatthew G. Knepley 
9082eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
9092eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
9102eabf88fSMatthew G. Knepley       }
9112eabf88fSMatthew G. Knepley     }
9122eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
9132eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
9142eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
9152eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
9162eabf88fSMatthew G. Knepley         PetscInt       size;
9172eabf88fSMatthew G. Knepley 
9182eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
9192eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
9202eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
9212eabf88fSMatthew G. Knepley       }
9222eabf88fSMatthew G. Knepley     }
9232eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
9242eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
9252eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
9262eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
9272eabf88fSMatthew G. Knepley         PetscInt       size;
9282eabf88fSMatthew G. Knepley 
9292eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
9302eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
9312eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
9322eabf88fSMatthew G. Knepley       }
9332eabf88fSMatthew G. Knepley     }
9342eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
9352eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
9362eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
9372eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
9382eabf88fSMatthew G. Knepley 
9392eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
9402eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
9412eabf88fSMatthew G. Knepley       }
9422eabf88fSMatthew G. Knepley     }
9432eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
9442eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
9452eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
9462eabf88fSMatthew G. Knepley       PetscInt       size;
9472eabf88fSMatthew G. Knepley 
9482eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
9492eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
9502eabf88fSMatthew G. Knepley     }
9512eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
9522eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
9532eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
9542eabf88fSMatthew G. Knepley       PetscInt       size;
9552eabf88fSMatthew G. Knepley 
9562eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
9572eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
9582eabf88fSMatthew G. Knepley     }
9592eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
9602eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
9612eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
9622eabf88fSMatthew G. Knepley       PetscInt       size;
9632eabf88fSMatthew G. Knepley 
9642eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
9652eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
9662eabf88fSMatthew G. Knepley     }
9672eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
9682eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
9692eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
9702eabf88fSMatthew G. Knepley 
9712eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
9722eabf88fSMatthew G. Knepley     }
9732eabf88fSMatthew G. Knepley     break;
9749b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
97527fcede3SMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart),
97627fcede3SMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
97727fcede3SMatthew G. Knepley     /* Interior cells have 6 faces */
97827fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
97927fcede3SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
98027fcede3SMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
98127fcede3SMatthew G. Knepley 
98227fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
98327fcede3SMatthew G. Knepley       }
98427fcede3SMatthew G. Knepley     }
98527fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces */
98627fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
98727fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
98827fcede3SMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
98927fcede3SMatthew G. Knepley 
99027fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
99127fcede3SMatthew G. Knepley       }
99227fcede3SMatthew G. Knepley     }
99327fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
99427fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
99527fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
99627fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
99727fcede3SMatthew G. Knepley         PetscInt       size;
99827fcede3SMatthew G. Knepley 
99927fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
100027fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
100127fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
100227fcede3SMatthew G. Knepley       }
100327fcede3SMatthew G. Knepley     }
100427fcede3SMatthew G. Knepley     /* Interior cell faces have 4 edges and 2 cells */
100527fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
100627fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
100727fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
100827fcede3SMatthew G. Knepley 
100927fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
101027fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
101127fcede3SMatthew G. Knepley       }
101227fcede3SMatthew G. Knepley     }
101327fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
101427fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
101527fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
101627fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
101727fcede3SMatthew G. Knepley         PetscInt       size;
101827fcede3SMatthew G. Knepley 
101927fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
102027fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
102127fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
102227fcede3SMatthew G. Knepley       }
102327fcede3SMatthew G. Knepley     }
102427fcede3SMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
102527fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
102627fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
102727fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r;
102827fcede3SMatthew G. Knepley 
102927fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
103027fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
103127fcede3SMatthew G. Knepley       }
103227fcede3SMatthew G. Knepley     }
103327fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
103427fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
103527fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
103627fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
103727fcede3SMatthew G. Knepley         PetscInt       size;
103827fcede3SMatthew G. Knepley 
103927fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
104027fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
104127fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
104227fcede3SMatthew G. Knepley       }
104327fcede3SMatthew G. Knepley     }
104427fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
104527fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
104627fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
104727fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
104827fcede3SMatthew G. Knepley         PetscInt       size;
104927fcede3SMatthew G. Knepley 
105027fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
105127fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
105227fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
105327fcede3SMatthew G. Knepley       }
105427fcede3SMatthew G. Knepley     }
105527fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
105627fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
105727fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
105827fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
105927fcede3SMatthew G. Knepley 
106027fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
106127fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
106227fcede3SMatthew G. Knepley       }
106327fcede3SMatthew G. Knepley     }
106427fcede3SMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
106527fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
106627fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
106727fcede3SMatthew G. Knepley       PetscInt       size;
106827fcede3SMatthew G. Knepley 
106927fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
107027fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
107127fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
107227fcede3SMatthew G. Knepley     }
107327fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
107427fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
107527fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
107627fcede3SMatthew G. Knepley       PetscInt       size;
107727fcede3SMatthew G. Knepley 
107827fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
107927fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
108027fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
108127fcede3SMatthew G. Knepley     }
108227fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
108327fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
108427fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
108527fcede3SMatthew G. Knepley 
108627fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
108727fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
108827fcede3SMatthew G. Knepley     }
108927fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
109027fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
109127fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
109227fcede3SMatthew G. Knepley       PetscInt       size;
109327fcede3SMatthew G. Knepley 
109427fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
109527fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
109627fcede3SMatthew G. Knepley     }
109727fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
109827fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
109927fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
110027fcede3SMatthew G. Knepley       PetscInt       size;
110127fcede3SMatthew G. Knepley 
110227fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
110327fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
110427fcede3SMatthew G. Knepley     }
110527fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
110627fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
110727fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
110827fcede3SMatthew G. Knepley       PetscInt       size;
110927fcede3SMatthew G. Knepley 
111027fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
111127fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
111227fcede3SMatthew G. Knepley     }
111327fcede3SMatthew G. Knepley     /* Interior cell vertices have 6 supports */
111427fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
111527fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
111627fcede3SMatthew G. Knepley 
111727fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
111827fcede3SMatthew G. Knepley     }
111927fcede3SMatthew G. Knepley     break;
112075d3a19aSMatthew G. Knepley   default:
112175d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
112275d3a19aSMatthew G. Knepley   }
112375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
112475d3a19aSMatthew G. Knepley }
112575d3a19aSMatthew G. Knepley 
112675d3a19aSMatthew G. Knepley #undef __FUNCT__
112775d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCones"
112886150812SJed Brown static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
112975d3a19aSMatthew G. Knepley {
1130b5da9499SMatthew G. Knepley   const PetscInt *faces, cellInd[4] = {0, 1, 2, 3};
11316ce3c06aSMatthew G. Knepley   PetscInt        cStart,    cEnd,    cMax,    vStart,    vEnd, vMax, fStart,    fEnd,    fMax,    eStart,    eEnd,    eMax;
11326ce3c06aSMatthew G. Knepley   PetscInt        cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew,    fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew;
11336ce3c06aSMatthew G. Knepley   PetscInt        depth, maxSupportSize, *supportRef, c, f, e, v, r, p;
113475d3a19aSMatthew G. Knepley   PetscErrorCode  ierr;
113575d3a19aSMatthew G. Knepley 
113675d3a19aSMatthew G. Knepley   PetscFunctionBegin;
11372a5d0125SJed Brown   if (!refiner) PetscFunctionReturn(0);
113875d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
113975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
114075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
114175d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
114275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
114375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
114475d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
114575d3a19aSMatthew G. Knepley   ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr);
114675d3a19aSMatthew G. Knepley   switch (refiner) {
11470314a74cSLawrence Mitchell   case REFINER_SIMPLEX_1D:
11480314a74cSLawrence Mitchell     /* Max support size of refined mesh is 2 */
11490314a74cSLawrence Mitchell     ierr = PetscMalloc1(2, &supportRef);CHKERRQ(ierr);
11500314a74cSLawrence Mitchell     /* All cells have 2 vertices */
11510314a74cSLawrence Mitchell     for (c = cStart; c < cEnd; ++c) {
11520314a74cSLawrence Mitchell       const PetscInt  newv = vStartNew + (vEnd - vStart) + (c - cStart);
11530314a74cSLawrence Mitchell 
11540314a74cSLawrence Mitchell       for (r = 0; r < 2; ++r) {
11550314a74cSLawrence Mitchell         const PetscInt newp = cStartNew + (c - cStart)*2 + r;
11560314a74cSLawrence Mitchell         const PetscInt *cone;
11570314a74cSLawrence Mitchell         PetscInt        coneNew[2];
11580314a74cSLawrence Mitchell 
11590314a74cSLawrence Mitchell         ierr             = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
11600314a74cSLawrence Mitchell         coneNew[0]       = vStartNew + (cone[0] - vStart);
11610314a74cSLawrence Mitchell         coneNew[1]       = vStartNew + (cone[1] - vStart);
11620314a74cSLawrence Mitchell         coneNew[(r+1)%2] = newv;
11630314a74cSLawrence Mitchell         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
11640314a74cSLawrence Mitchell #if 1
11650314a74cSLawrence Mitchell         if ((newp < cStartNew) || (newp >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp, cStartNew, cEndNew);
11660314a74cSLawrence Mitchell         for (p = 0; p < 2; ++p) {
11670314a74cSLawrence 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);
11680314a74cSLawrence Mitchell         }
11690314a74cSLawrence Mitchell #endif
11700314a74cSLawrence Mitchell       }
11710314a74cSLawrence Mitchell     }
11720314a74cSLawrence Mitchell     /* Old vertices have identical supports */
11730314a74cSLawrence Mitchell     for (v = vStart; v < vEnd; ++v) {
11740314a74cSLawrence Mitchell       const PetscInt  newp = vStartNew + (v - vStart);
11750314a74cSLawrence Mitchell       const PetscInt *support, *cone;
11760314a74cSLawrence Mitchell       PetscInt        size, s;
11770314a74cSLawrence Mitchell 
11780314a74cSLawrence Mitchell       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
11790314a74cSLawrence Mitchell       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
11800314a74cSLawrence Mitchell       for (s = 0; s < size; ++s) {
11810314a74cSLawrence Mitchell         PetscInt r = 0;
11820314a74cSLawrence Mitchell 
11830314a74cSLawrence Mitchell         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
11840314a74cSLawrence Mitchell         if (cone[1] == v) r = 1;
11850314a74cSLawrence Mitchell         supportRef[s] = cStartNew + (support[s] - cStart)*2 + r;
11860314a74cSLawrence Mitchell       }
11870314a74cSLawrence Mitchell       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
11880314a74cSLawrence Mitchell #if 1
11890314a74cSLawrence Mitchell       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
11900314a74cSLawrence Mitchell       for (p = 0; p < size; ++p) {
11910314a74cSLawrence 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);
11920314a74cSLawrence Mitchell       }
11930314a74cSLawrence Mitchell #endif
11940314a74cSLawrence Mitchell     }
11950314a74cSLawrence Mitchell     /* Cell vertices have support of 2 cells */
11960314a74cSLawrence Mitchell     for (c = cStart; c < cEnd; ++c) {
11970314a74cSLawrence Mitchell       const PetscInt  newp = vStartNew + (vEnd - vStart) + (c - cStart);
11980314a74cSLawrence Mitchell 
11990314a74cSLawrence Mitchell       supportRef[0] = cStartNew + (c - cStart)*2 + 0;
12000314a74cSLawrence Mitchell       supportRef[1] = cStartNew + (c - cStart)*2 + 1;
12010314a74cSLawrence Mitchell       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
12020314a74cSLawrence Mitchell #if 1
12030314a74cSLawrence Mitchell       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
12040314a74cSLawrence Mitchell       for (p = 0; p < 2; ++p) {
12050314a74cSLawrence 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);
12060314a74cSLawrence Mitchell       }
12070314a74cSLawrence Mitchell #endif
12080314a74cSLawrence Mitchell     }
12090314a74cSLawrence Mitchell     ierr = PetscFree(supportRef);CHKERRQ(ierr);
12100314a74cSLawrence Mitchell     break;
12119b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
121275d3a19aSMatthew G. Knepley     /*
121375d3a19aSMatthew G. Knepley      2
121475d3a19aSMatthew G. Knepley      |\
121575d3a19aSMatthew G. Knepley      | \
121675d3a19aSMatthew G. Knepley      |  \
121775d3a19aSMatthew G. Knepley      |   \
121875d3a19aSMatthew G. Knepley      | C  \
121975d3a19aSMatthew G. Knepley      |     \
122075d3a19aSMatthew G. Knepley      |      \
122175d3a19aSMatthew G. Knepley      2---1---1
122275d3a19aSMatthew G. Knepley      |\  D  / \
122375d3a19aSMatthew G. Knepley      | 2   0   \
122475d3a19aSMatthew G. Knepley      |A \ /  B  \
122575d3a19aSMatthew G. Knepley      0---0-------1
122675d3a19aSMatthew G. Knepley      */
122775d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
122875d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
122975d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
123075d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
123175d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
123275d3a19aSMatthew G. Knepley 
123375d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
123475d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
123575d3a19aSMatthew G. Knepley       /* A triangle */
123675d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
123775d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
123875d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
123975d3a19aSMatthew G. Knepley       orntNew[1] = -2;
124075d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
124175d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
124275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
124375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
124475d3a19aSMatthew G. Knepley #if 1
124575d3a19aSMatthew 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);
124675d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
124775d3a19aSMatthew 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);
124875d3a19aSMatthew G. Knepley       }
124975d3a19aSMatthew G. Knepley #endif
125075d3a19aSMatthew G. Knepley       /* B triangle */
125175d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
125275d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
125375d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
125475d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
125575d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
125675d3a19aSMatthew G. Knepley       orntNew[2] = -2;
125775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
125875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
125975d3a19aSMatthew G. Knepley #if 1
126075d3a19aSMatthew 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);
126175d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
126275d3a19aSMatthew 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);
126375d3a19aSMatthew G. Knepley       }
126475d3a19aSMatthew G. Knepley #endif
126575d3a19aSMatthew G. Knepley       /* C triangle */
126675d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
126775d3a19aSMatthew G. Knepley       orntNew[0] = -2;
126875d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
126975d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
127075d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
127175d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
127275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
127375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
127475d3a19aSMatthew G. Knepley #if 1
127575d3a19aSMatthew 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);
127675d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
127775d3a19aSMatthew 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);
127875d3a19aSMatthew G. Knepley       }
127975d3a19aSMatthew G. Knepley #endif
128075d3a19aSMatthew G. Knepley       /* D triangle */
128175d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
128275d3a19aSMatthew G. Knepley       orntNew[0] = 0;
128375d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
128475d3a19aSMatthew G. Knepley       orntNew[1] = 0;
128575d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
128675d3a19aSMatthew G. Knepley       orntNew[2] = 0;
128775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
128875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
128975d3a19aSMatthew G. Knepley #if 1
129075d3a19aSMatthew 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);
129175d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
129275d3a19aSMatthew 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);
129375d3a19aSMatthew G. Knepley       }
129475d3a19aSMatthew G. Knepley #endif
129575d3a19aSMatthew G. Knepley     }
129675d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
129775d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1298854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
129975d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
130075d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
130175d3a19aSMatthew G. Knepley 
130275d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
130375d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1304297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
130575d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
130675d3a19aSMatthew G. Knepley 
130775d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
130875d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
130975d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
131075d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
131175d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
131275d3a19aSMatthew G. Knepley #if 1
131375d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
131475d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
131575d3a19aSMatthew 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);
131675d3a19aSMatthew G. Knepley         }
131775d3a19aSMatthew G. Knepley #endif
131875d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
131975d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
132075d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
132175d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
132275d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1323297d2bf4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
132475d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
132575d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
132675d3a19aSMatthew G. Knepley           }
1327297d2bf4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
132875d3a19aSMatthew G. Knepley         }
132975d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
133075d3a19aSMatthew G. Knepley #if 1
133175d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
133275d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
133375d3a19aSMatthew 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);
133475d3a19aSMatthew G. Knepley         }
133575d3a19aSMatthew G. Knepley #endif
133675d3a19aSMatthew G. Knepley       }
133775d3a19aSMatthew G. Knepley     }
133875d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
133975d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
134075d3a19aSMatthew G. Knepley       const PetscInt *cone;
134175d3a19aSMatthew G. Knepley 
134275d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
134375d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
134475d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
134575d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
134675d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
134775d3a19aSMatthew G. Knepley 
134875d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
134975d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
135075d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
135175d3a19aSMatthew G. Knepley #if 1
135275d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
135375d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
135475d3a19aSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
135575d3a19aSMatthew G. Knepley         }
135675d3a19aSMatthew G. Knepley #endif
135775d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
135875d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
135975d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
136075d3a19aSMatthew G. Knepley #if 1
136175d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
136275d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
136375d3a19aSMatthew G. Knepley           if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
136475d3a19aSMatthew G. Knepley         }
136575d3a19aSMatthew G. Knepley #endif
136675d3a19aSMatthew G. Knepley       }
136775d3a19aSMatthew G. Knepley     }
136875d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
136975d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
137075d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
137175d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
137275d3a19aSMatthew G. Knepley       PetscInt        size, s;
137375d3a19aSMatthew G. Knepley 
137475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
137575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
137675d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
137775d3a19aSMatthew G. Knepley         PetscInt r = 0;
137875d3a19aSMatthew G. Knepley 
137975d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
138075d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
138175d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
138275d3a19aSMatthew G. Knepley       }
138375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
138475d3a19aSMatthew G. Knepley #if 1
138575d3a19aSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
138675d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
138775d3a19aSMatthew G. Knepley         if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
138875d3a19aSMatthew G. Knepley       }
138975d3a19aSMatthew G. Knepley #endif
139075d3a19aSMatthew G. Knepley     }
139175d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
139275d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
139375d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
139475d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
139575d3a19aSMatthew G. Knepley       PetscInt        size, s;
139675d3a19aSMatthew G. Knepley 
139775d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
139875d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
139975d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
140075d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
140175d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
140275d3a19aSMatthew G. Knepley         PetscInt r = 0;
140375d3a19aSMatthew G. Knepley 
140475d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
140575d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
140675d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
140775d3a19aSMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
140875d3a19aSMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
140975d3a19aSMatthew G. Knepley       }
141075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
141175d3a19aSMatthew G. Knepley #if 1
141275d3a19aSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
141375d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
141475d3a19aSMatthew G. Knepley         if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
141575d3a19aSMatthew G. Knepley       }
141675d3a19aSMatthew G. Knepley #endif
141775d3a19aSMatthew G. Knepley     }
141875d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
141975d3a19aSMatthew G. Knepley     break;
14209b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
142175d3a19aSMatthew G. Knepley     /*
142275d3a19aSMatthew G. Knepley      3---------2---------2
142375d3a19aSMatthew G. Knepley      |         |         |
142475d3a19aSMatthew G. Knepley      |    D    2    C    |
142575d3a19aSMatthew G. Knepley      |         |         |
142675d3a19aSMatthew G. Knepley      3----3----0----1----1
142775d3a19aSMatthew G. Knepley      |         |         |
142875d3a19aSMatthew G. Knepley      |    A    0    B    |
142975d3a19aSMatthew G. Knepley      |         |         |
143075d3a19aSMatthew G. Knepley      0---------0---------1
143175d3a19aSMatthew G. Knepley      */
143275d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
143375d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
143475d3a19aSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*4;
143575d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
143675d3a19aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
143775d3a19aSMatthew G. Knepley 
143875d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
143975d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
144075d3a19aSMatthew G. Knepley       /* A quad */
144175d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
144275d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
144375d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
144475d3a19aSMatthew G. Knepley       orntNew[1] = 0;
144575d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
144675d3a19aSMatthew G. Knepley       orntNew[2] = -2;
144775d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
144875d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
144975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
145075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
145175d3a19aSMatthew G. Knepley #if 1
145275d3a19aSMatthew 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);
145375d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
145475d3a19aSMatthew 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);
145575d3a19aSMatthew G. Knepley       }
145675d3a19aSMatthew G. Knepley #endif
145775d3a19aSMatthew G. Knepley       /* B quad */
145875d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
145975d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
146075d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
146175d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
146275d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
146375d3a19aSMatthew G. Knepley       orntNew[2] = 0;
146475d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
146575d3a19aSMatthew G. Knepley       orntNew[3] = -2;
146675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
146775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
146875d3a19aSMatthew G. Knepley #if 1
146975d3a19aSMatthew 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);
147075d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
147175d3a19aSMatthew 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);
147275d3a19aSMatthew G. Knepley       }
147375d3a19aSMatthew G. Knepley #endif
147475d3a19aSMatthew G. Knepley       /* C quad */
147575d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
147675d3a19aSMatthew G. Knepley       orntNew[0] = -2;
147775d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
147875d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
147975d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
148075d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
148175d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
148275d3a19aSMatthew G. Knepley       orntNew[3] = 0;
148375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
148475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
148575d3a19aSMatthew G. Knepley #if 1
148675d3a19aSMatthew 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);
148775d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
148875d3a19aSMatthew 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);
148975d3a19aSMatthew G. Knepley       }
149075d3a19aSMatthew G. Knepley #endif
149175d3a19aSMatthew G. Knepley       /* D quad */
149275d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
149375d3a19aSMatthew G. Knepley       orntNew[0] = 0;
149475d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
149575d3a19aSMatthew G. Knepley       orntNew[1] = -2;
149675d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
149775d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
149875d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
149975d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
150075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
150175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
150275d3a19aSMatthew G. Knepley #if 1
150375d3a19aSMatthew 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);
150475d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
150575d3a19aSMatthew 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);
150675d3a19aSMatthew G. Knepley       }
150775d3a19aSMatthew G. Knepley #endif
150875d3a19aSMatthew G. Knepley     }
150975d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
151075d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1511854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
151275d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
151375d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
151475d3a19aSMatthew G. Knepley 
151575d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
151675d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1517455d6cd4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
151875d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
151975d3a19aSMatthew G. Knepley 
152075d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
152175d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
152275d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
152375d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
152475d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
152575d3a19aSMatthew G. Knepley #if 1
152675d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
152775d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
152875d3a19aSMatthew 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);
152975d3a19aSMatthew G. Knepley         }
153075d3a19aSMatthew G. Knepley #endif
153175d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
153275d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
153375d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
153475d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
153575d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1536455d6cd4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
153775d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
153875d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
153975d3a19aSMatthew G. Knepley           }
1540455d6cd4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
154175d3a19aSMatthew G. Knepley         }
154275d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
154375d3a19aSMatthew G. Knepley #if 1
154475d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
154575d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
154675d3a19aSMatthew 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);
154775d3a19aSMatthew G. Knepley         }
154875d3a19aSMatthew G. Knepley #endif
154975d3a19aSMatthew G. Knepley       }
155075d3a19aSMatthew G. Knepley     }
155175d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
155275d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
155375d3a19aSMatthew G. Knepley       const PetscInt *cone;
155475d3a19aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
155575d3a19aSMatthew G. Knepley 
155675d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
155775d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
155875d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
155975d3a19aSMatthew G. Knepley 
156075d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
156175d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd    - fStart) + (c - cStart);
156275d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
156375d3a19aSMatthew G. Knepley #if 1
156475d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
156575d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
156675d3a19aSMatthew 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);
156775d3a19aSMatthew G. Knepley         }
156875d3a19aSMatthew G. Knepley #endif
156975d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
157075d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
157175d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
157275d3a19aSMatthew G. Knepley #if 1
157375d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
157475d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
157575d3a19aSMatthew 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);
157675d3a19aSMatthew G. Knepley         }
157775d3a19aSMatthew G. Knepley #endif
157875d3a19aSMatthew G. Knepley       }
157975d3a19aSMatthew G. Knepley     }
158075d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
158175d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
158275d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
158375d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
158475d3a19aSMatthew G. Knepley       PetscInt        size, s;
158575d3a19aSMatthew G. Knepley 
158675d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
158775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
158875d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
158975d3a19aSMatthew G. Knepley         PetscInt r = 0;
159075d3a19aSMatthew G. Knepley 
159175d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
159275d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
159375d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
159475d3a19aSMatthew G. Knepley       }
159575d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
159675d3a19aSMatthew G. Knepley #if 1
159775d3a19aSMatthew 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);
159875d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
159975d3a19aSMatthew 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);
160075d3a19aSMatthew G. Knepley       }
160175d3a19aSMatthew G. Knepley #endif
160275d3a19aSMatthew G. Knepley     }
160375d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
160475d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
160575d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
160675d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
160775d3a19aSMatthew G. Knepley       PetscInt        size, s;
160875d3a19aSMatthew G. Knepley 
160975d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
161075d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
161175d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
161275d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
161375d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
161475d3a19aSMatthew G. Knepley         PetscInt r = 0;
161575d3a19aSMatthew G. Knepley 
161675d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
161775d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
161875d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
161975d3a19aSMatthew G. Knepley         else if (cone[3] == f) r = 3;
162075d3a19aSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r;
162175d3a19aSMatthew G. Knepley       }
162275d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
162375d3a19aSMatthew G. Knepley #if 1
162475d3a19aSMatthew 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);
162575d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
162675d3a19aSMatthew 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);
162775d3a19aSMatthew G. Knepley       }
162875d3a19aSMatthew G. Knepley #endif
162975d3a19aSMatthew G. Knepley     }
163075d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
163175d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
163275d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
163375d3a19aSMatthew G. Knepley       PetscInt       supportNew[4];
163475d3a19aSMatthew G. Knepley 
163575d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
163675d3a19aSMatthew G. Knepley         supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
163775d3a19aSMatthew G. Knepley       }
163875d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
163975d3a19aSMatthew G. Knepley     }
1640da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
164175d3a19aSMatthew G. Knepley     break;
16429b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
164375d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
164475d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
164575d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
164675d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
1647149f48fdSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr);
164875d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
164975d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
165075d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
165175d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
165275d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
165375d3a19aSMatthew G. Knepley 
165475d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
165575d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
165675d3a19aSMatthew G. Knepley       /* A triangle */
165775d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
165875d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
165975d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
166075d3a19aSMatthew G. Knepley       orntNew[1] = -2;
166175d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
166275d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
166375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
166475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
166575d3a19aSMatthew G. Knepley #if 1
1666149f48fdSMatthew 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);
166775d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1668149f48fdSMatthew 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);
166975d3a19aSMatthew G. Knepley       }
167075d3a19aSMatthew G. Knepley #endif
167175d3a19aSMatthew G. Knepley       /* B triangle */
167275d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
167375d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
167475d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
167575d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
167675d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
167775d3a19aSMatthew G. Knepley       orntNew[2] = -2;
167875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
167975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
168075d3a19aSMatthew G. Knepley #if 1
1681a97b51b8SMatthew 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);
168275d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1683a97b51b8SMatthew 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);
168475d3a19aSMatthew G. Knepley       }
168575d3a19aSMatthew G. Knepley #endif
168675d3a19aSMatthew G. Knepley       /* C triangle */
168775d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
168875d3a19aSMatthew G. Knepley       orntNew[0] = -2;
168975d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
169075d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
169175d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
169275d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
169375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
169475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
169575d3a19aSMatthew G. Knepley #if 1
1696a97b51b8SMatthew 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);
169775d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1698a97b51b8SMatthew 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);
169975d3a19aSMatthew G. Knepley       }
170075d3a19aSMatthew G. Knepley #endif
170175d3a19aSMatthew G. Knepley       /* D triangle */
170275d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
170375d3a19aSMatthew G. Knepley       orntNew[0] = 0;
170475d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
170575d3a19aSMatthew G. Knepley       orntNew[1] = 0;
170675d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
170775d3a19aSMatthew G. Knepley       orntNew[2] = 0;
170875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
170975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
171075d3a19aSMatthew G. Knepley #if 1
1711a97b51b8SMatthew 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);
171275d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1713a97b51b8SMatthew 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);
171475d3a19aSMatthew G. Knepley       }
171575d3a19aSMatthew G. Knepley #endif
171675d3a19aSMatthew G. Knepley     }
171775d3a19aSMatthew G. Knepley     /*
171875d3a19aSMatthew G. Knepley      2----3----3
171975d3a19aSMatthew G. Knepley      |         |
172075d3a19aSMatthew G. Knepley      |    B    |
172175d3a19aSMatthew G. Knepley      |         |
172275d3a19aSMatthew G. Knepley      0----4--- 1
172375d3a19aSMatthew G. Knepley      |         |
172475d3a19aSMatthew G. Knepley      |    A    |
172575d3a19aSMatthew G. Knepley      |         |
172675d3a19aSMatthew G. Knepley      0----2----1
172775d3a19aSMatthew G. Knepley      */
172875d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
172975d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
173075d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
173175d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
1732ea00e70eSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4], r;
173375d3a19aSMatthew G. Knepley 
173475d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
173575d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1736ea00e70eSMatthew G. Knepley       r    = (ornt[0] < 0 ? 1 : 0);
173775d3a19aSMatthew G. Knepley       /* A quad */
1738ea00e70eSMatthew G. Knepley       coneNew[0]   = fStartNew + (cone[0] - fStart)*2 + r;
173975d3a19aSMatthew G. Knepley       orntNew[0]   = ornt[0];
1740ea00e70eSMatthew G. Knepley       coneNew[1]   = fStartNew + (cone[1] - fStart)*2 + r;
174175d3a19aSMatthew G. Knepley       orntNew[1]   = ornt[1];
1742ea00e70eSMatthew G. Knepley       coneNew[2+r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax);
1743ea00e70eSMatthew G. Knepley       orntNew[2+r] = 0;
1744ea00e70eSMatthew G. Knepley       coneNew[3-r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
1745ea00e70eSMatthew G. Knepley       orntNew[3-r] = 0;
174675d3a19aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
174775d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
174875d3a19aSMatthew G. Knepley #if 1
174975d3a19aSMatthew 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);
175075d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
175175d3a19aSMatthew 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);
175275d3a19aSMatthew G. Knepley       }
175375d3a19aSMatthew G. Knepley #endif
175475d3a19aSMatthew G. Knepley       /* B quad */
1755ea00e70eSMatthew G. Knepley       coneNew[0]   = fStartNew + (cone[0] - fStart)*2 + 1-r;
175675d3a19aSMatthew G. Knepley       orntNew[0]   = ornt[0];
1757ea00e70eSMatthew G. Knepley       coneNew[1]   = fStartNew + (cone[1] - fStart)*2 + 1-r;
175875d3a19aSMatthew G. Knepley       orntNew[1]   = ornt[1];
1759ea00e70eSMatthew G. Knepley       coneNew[2+r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
1760ea00e70eSMatthew G. Knepley       orntNew[2+r] = 0;
1761ea00e70eSMatthew G. Knepley       coneNew[3-r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax);
1762ea00e70eSMatthew G. Knepley       orntNew[3-r] = 0;
176375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
176475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
176575d3a19aSMatthew G. Knepley #if 1
176675d3a19aSMatthew 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);
176775d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
176875d3a19aSMatthew 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);
176975d3a19aSMatthew G. Knepley       }
177075d3a19aSMatthew G. Knepley #endif
177175d3a19aSMatthew G. Knepley     }
177275d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
177375d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1774854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
177575d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
177675d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
177775d3a19aSMatthew G. Knepley 
177875d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
177975d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1780297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
178175d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
178275d3a19aSMatthew G. Knepley 
178375d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
178475d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
178575d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
178675d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
178775d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
178875d3a19aSMatthew G. Knepley #if 1
178975d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
179075d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
179175d3a19aSMatthew 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);
179275d3a19aSMatthew G. Knepley         }
179375d3a19aSMatthew G. Knepley #endif
179475d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
179575d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
179675d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
179775d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
179875d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1799297d2bf4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
1800ea00e70eSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == f) break;
1801ea00e70eSMatthew G. Knepley           if (support[s] >= cMax) {
1802ea00e70eSMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r);
1803ea00e70eSMatthew G. Knepley           } else {
1804297d2bf4SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
180575d3a19aSMatthew G. Knepley           }
180675d3a19aSMatthew G. Knepley         }
180775d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
180875d3a19aSMatthew G. Knepley #if 1
180975d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
181075d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
181175d3a19aSMatthew 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);
181275d3a19aSMatthew G. Knepley         }
181375d3a19aSMatthew G. Knepley #endif
181475d3a19aSMatthew G. Knepley       }
181575d3a19aSMatthew G. Knepley     }
181675d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
181775d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
181875d3a19aSMatthew G. Knepley       const PetscInt *cone;
181975d3a19aSMatthew G. Knepley 
182075d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
182175d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
182275d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
182375d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
182475d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
182575d3a19aSMatthew G. Knepley 
182675d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
182775d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
182875d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
182975d3a19aSMatthew G. Knepley #if 1
183075d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
183175d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
183275d3a19aSMatthew 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);
183375d3a19aSMatthew G. Knepley         }
183475d3a19aSMatthew G. Knepley #endif
183575d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
183675d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
183775d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
183875d3a19aSMatthew G. Knepley #if 1
183975d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
184075d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
184175d3a19aSMatthew 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);
184275d3a19aSMatthew G. Knepley         }
184375d3a19aSMatthew G. Knepley #endif
184475d3a19aSMatthew G. Knepley       }
184575d3a19aSMatthew G. Knepley     }
184675d3a19aSMatthew G. Knepley     /* Interior hybrid faces have 2 vertices and the same cells */
184775d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
184875d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
1849ea00e70eSMatthew G. Knepley       const PetscInt *cone, *ornt;
185075d3a19aSMatthew G. Knepley       const PetscInt *support;
185175d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
185275d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
185375d3a19aSMatthew G. Knepley       PetscInt        size, s, r;
185475d3a19aSMatthew G. Knepley 
185575d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
185675d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
185775d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
185875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
185975d3a19aSMatthew G. Knepley #if 1
186075d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
186175d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
186275d3a19aSMatthew 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);
186375d3a19aSMatthew G. Knepley       }
186475d3a19aSMatthew G. Knepley #endif
186575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
186675d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
186775d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
186875d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1869ea00e70eSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
187075d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r) {
187175d3a19aSMatthew G. Knepley           if (cone[r+2] == f) break;
187275d3a19aSMatthew G. Knepley         }
1873ea00e70eSMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r);
187475d3a19aSMatthew G. Knepley       }
187575d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
187675d3a19aSMatthew G. Knepley #if 1
187775d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
187875d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
187975d3a19aSMatthew 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);
188075d3a19aSMatthew G. Knepley       }
188175d3a19aSMatthew G. Knepley #endif
188275d3a19aSMatthew G. Knepley     }
188375d3a19aSMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
188475d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
188575d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
188675d3a19aSMatthew G. Knepley       const PetscInt *cone;
188775d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
188875d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
188975d3a19aSMatthew G. Knepley 
189075d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
189175d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
189275d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
189375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
189475d3a19aSMatthew G. Knepley #if 1
189575d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
189675d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
189775d3a19aSMatthew 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);
189875d3a19aSMatthew G. Knepley       }
189975d3a19aSMatthew G. Knepley #endif
190075d3a19aSMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
190175d3a19aSMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
190275d3a19aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
190375d3a19aSMatthew G. Knepley #if 1
190475d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
190575d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
190675d3a19aSMatthew 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);
190775d3a19aSMatthew G. Knepley       }
190875d3a19aSMatthew G. Knepley #endif
190975d3a19aSMatthew G. Knepley     }
191075d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
191175d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
191275d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
191375d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
191475d3a19aSMatthew G. Knepley       PetscInt        size, s;
191575d3a19aSMatthew G. Knepley 
191675d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
191775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
191875d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
191975d3a19aSMatthew G. Knepley         if (support[s] >= fMax) {
192075d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax);
192175d3a19aSMatthew G. Knepley         } else {
192275d3a19aSMatthew G. Knepley           PetscInt r = 0;
192375d3a19aSMatthew G. Knepley 
192475d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
192575d3a19aSMatthew G. Knepley           if (cone[1] == v) r = 1;
192675d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
192775d3a19aSMatthew G. Knepley         }
192875d3a19aSMatthew G. Knepley       }
192975d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
193075d3a19aSMatthew G. Knepley #if 1
193175d3a19aSMatthew 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);
193275d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
193375d3a19aSMatthew 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);
193475d3a19aSMatthew G. Knepley       }
193575d3a19aSMatthew G. Knepley #endif
193675d3a19aSMatthew G. Knepley     }
193775d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
193875d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
193975d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
194075d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
194175d3a19aSMatthew G. Knepley       PetscInt        size, newSize = 2, s;
194275d3a19aSMatthew G. Knepley 
194375d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
194475d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
194575d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
194675d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
194775d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
194875d3a19aSMatthew G. Knepley         PetscInt r = 0;
194975d3a19aSMatthew G. Knepley 
195075d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
195175d3a19aSMatthew G. Knepley         if (support[s] >= cMax) {
195275d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax);
195375d3a19aSMatthew G. Knepley 
195475d3a19aSMatthew G. Knepley           newSize += 1;
195575d3a19aSMatthew G. Knepley         } else {
195675d3a19aSMatthew G. Knepley           if      (cone[1] == f) r = 1;
195775d3a19aSMatthew G. Knepley           else if (cone[2] == f) r = 2;
195875d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
195975d3a19aSMatthew G. Knepley           supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r;
196075d3a19aSMatthew G. Knepley 
196175d3a19aSMatthew G. Knepley           newSize += 2;
196275d3a19aSMatthew G. Knepley         }
196375d3a19aSMatthew G. Knepley       }
196475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
196575d3a19aSMatthew G. Knepley #if 1
196675d3a19aSMatthew 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);
196775d3a19aSMatthew G. Knepley       for (p = 0; p < newSize; ++p) {
196875d3a19aSMatthew 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);
196975d3a19aSMatthew G. Knepley       }
197075d3a19aSMatthew G. Knepley #endif
197175d3a19aSMatthew G. Knepley     }
197275d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
197375d3a19aSMatthew G. Knepley     break;
19749b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
1975a97b51b8SMatthew G. Knepley     /* Hybrid Hex 2D */
1976a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
1977a97b51b8SMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
1978a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
1979a97b51b8SMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
1980a97b51b8SMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr);
1981a97b51b8SMatthew G. Knepley     /* Interior cells have 4 faces */
1982a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
1983a97b51b8SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
1984a97b51b8SMatthew G. Knepley       const PetscInt *cone, *ornt;
1985a97b51b8SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
1986a97b51b8SMatthew G. Knepley 
1987a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1988a97b51b8SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1989a97b51b8SMatthew G. Knepley       /* A quad */
1990a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
1991a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
1992a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 0;
1993a97b51b8SMatthew G. Knepley       orntNew[1] = 0;
1994a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 3;
1995a97b51b8SMatthew G. Knepley       orntNew[2] = -2;
1996a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
1997a97b51b8SMatthew G. Knepley       orntNew[3] = ornt[3];
1998a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
1999a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2000a97b51b8SMatthew G. Knepley #if 1
2001a97b51b8SMatthew 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);
2002a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2003a97b51b8SMatthew 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);
2004a97b51b8SMatthew G. Knepley       }
2005a97b51b8SMatthew G. Knepley #endif
2006a97b51b8SMatthew G. Knepley       /* B quad */
2007a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2008a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2009a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2010a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2011a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 1;
2012a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
2013a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 0;
2014a97b51b8SMatthew G. Knepley       orntNew[3] = -2;
2015a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2016a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2017a97b51b8SMatthew G. Knepley #if 1
2018a97b51b8SMatthew 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);
2019a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2020a97b51b8SMatthew 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);
2021a97b51b8SMatthew G. Knepley       }
2022a97b51b8SMatthew G. Knepley #endif
2023a97b51b8SMatthew G. Knepley       /* C quad */
2024a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 1;
2025a97b51b8SMatthew G. Knepley       orntNew[0] = -2;
2026a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2027a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2028a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
2029a97b51b8SMatthew G. Knepley       orntNew[2] = ornt[2];
2030a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 2;
2031a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
2032a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2033a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2034a97b51b8SMatthew G. Knepley #if 1
2035a97b51b8SMatthew 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);
2036a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2037a97b51b8SMatthew 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);
2038a97b51b8SMatthew G. Knepley       }
2039a97b51b8SMatthew G. Knepley #endif
2040a97b51b8SMatthew G. Knepley       /* D quad */
2041a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 3;
2042a97b51b8SMatthew G. Knepley       orntNew[0] = 0;
2043a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 2;
2044a97b51b8SMatthew G. Knepley       orntNew[1] = -2;
2045a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
2046a97b51b8SMatthew G. Knepley       orntNew[2] = ornt[2];
2047a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
2048a97b51b8SMatthew G. Knepley       orntNew[3] = ornt[3];
2049a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2050a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2051a97b51b8SMatthew G. Knepley #if 1
2052a97b51b8SMatthew 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);
2053a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2054a97b51b8SMatthew 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);
2055a97b51b8SMatthew G. Knepley       }
2056a97b51b8SMatthew G. Knepley #endif
2057a97b51b8SMatthew G. Knepley     }
2058a97b51b8SMatthew G. Knepley     /*
2059a97b51b8SMatthew G. Knepley      2----3----3
2060a97b51b8SMatthew G. Knepley      |         |
2061a97b51b8SMatthew G. Knepley      |    B    |
2062a97b51b8SMatthew G. Knepley      |         |
2063a97b51b8SMatthew G. Knepley      0----4--- 1
2064a97b51b8SMatthew G. Knepley      |         |
2065a97b51b8SMatthew G. Knepley      |    A    |
2066a97b51b8SMatthew G. Knepley      |         |
2067a97b51b8SMatthew G. Knepley      0----2----1
2068a97b51b8SMatthew G. Knepley      */
2069a97b51b8SMatthew G. Knepley     /* Hybrid cells have 4 faces */
2070a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
2071a97b51b8SMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
2072a97b51b8SMatthew G. Knepley       const PetscInt *cone, *ornt;
2073a97b51b8SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
2074a97b51b8SMatthew G. Knepley 
2075a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2076a97b51b8SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2077a97b51b8SMatthew G. Knepley       /* A quad */
2078a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2079a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2080a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2081a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2082a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax);
2083a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
2084a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (fEnd    - fMax) + (c - cMax);
2085a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
2086a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2087a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2088a97b51b8SMatthew G. Knepley #if 1
2089a97b51b8SMatthew 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);
2090a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2091a97b51b8SMatthew 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);
2092a97b51b8SMatthew G. Knepley       }
2093a97b51b8SMatthew G. Knepley #endif
2094a97b51b8SMatthew G. Knepley       /* B quad */
2095a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2096a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2097a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2098a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2099a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (fEnd    - fMax) + (c - cMax);
2100a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
2101a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax);
2102a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
2103a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2104a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2105a97b51b8SMatthew G. Knepley #if 1
2106a97b51b8SMatthew 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);
2107a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2108a97b51b8SMatthew 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);
2109a97b51b8SMatthew G. Knepley       }
2110a97b51b8SMatthew G. Knepley #endif
2111a97b51b8SMatthew G. Knepley     }
2112a97b51b8SMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
2113a97b51b8SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2114854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
2115a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
2116a97b51b8SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
2117a97b51b8SMatthew G. Knepley 
2118a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
2119a97b51b8SMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
2120a97b51b8SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
2121a97b51b8SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
2122a97b51b8SMatthew G. Knepley 
2123a97b51b8SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2124a97b51b8SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
2125a97b51b8SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
2126a97b51b8SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
2127a97b51b8SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2128a97b51b8SMatthew G. Knepley #if 1
2129a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2130a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2131a97b51b8SMatthew 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);
2132a97b51b8SMatthew G. Knepley         }
2133a97b51b8SMatthew G. Knepley #endif
2134a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2135a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2136a97b51b8SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2137a97b51b8SMatthew G. Knepley           if (support[s] >= cMax) {
2138a97b51b8SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
2139a97b51b8SMatthew G. Knepley           } else {
2140a97b51b8SMatthew G. Knepley             ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2141a97b51b8SMatthew G. Knepley             ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2142a97b51b8SMatthew G. Knepley             ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2143a97b51b8SMatthew G. Knepley             for (c = 0; c < coneSize; ++c) {
2144a97b51b8SMatthew G. Knepley               if (cone[c] == f) break;
2145a97b51b8SMatthew G. Knepley             }
2146a97b51b8SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
2147a97b51b8SMatthew G. Knepley           }
2148a97b51b8SMatthew G. Knepley         }
2149a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2150a97b51b8SMatthew G. Knepley #if 1
2151a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2152a97b51b8SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2153a97b51b8SMatthew 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);
2154a97b51b8SMatthew G. Knepley         }
2155a97b51b8SMatthew G. Knepley #endif
2156a97b51b8SMatthew G. Knepley       }
2157a97b51b8SMatthew G. Knepley     }
2158a97b51b8SMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
2159a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
2160a97b51b8SMatthew G. Knepley       const PetscInt *cone;
2161a97b51b8SMatthew G. Knepley 
2162a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2163a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2164a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
2165a97b51b8SMatthew G. Knepley         PetscInt       coneNew[2], supportNew[2];
2166a97b51b8SMatthew G. Knepley 
2167a97b51b8SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2168a97b51b8SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fMax    - fStart) + (c - cStart);
2169a97b51b8SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2170a97b51b8SMatthew G. Knepley #if 1
2171a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2172a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2173a97b51b8SMatthew 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);
2174a97b51b8SMatthew G. Knepley         }
2175a97b51b8SMatthew G. Knepley #endif
2176a97b51b8SMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
2177a97b51b8SMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
2178a97b51b8SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2179a97b51b8SMatthew G. Knepley #if 1
2180a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2181a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2182a97b51b8SMatthew 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);
2183a97b51b8SMatthew G. Knepley         }
2184a97b51b8SMatthew G. Knepley #endif
2185a97b51b8SMatthew G. Knepley       }
2186a97b51b8SMatthew G. Knepley     }
2187a97b51b8SMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
2188a97b51b8SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
2189a97b51b8SMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
2190a97b51b8SMatthew G. Knepley       const PetscInt *cone, *support;
2191a97b51b8SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
2192a97b51b8SMatthew G. Knepley       PetscInt        size, s, r;
2193a97b51b8SMatthew G. Knepley 
2194a97b51b8SMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2195a97b51b8SMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
2196a97b51b8SMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
2197a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);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 < 2; ++p) {
2201a97b51b8SMatthew 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);
2202a97b51b8SMatthew G. Knepley       }
2203a97b51b8SMatthew G. Knepley #endif
2204a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
2205a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2206a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2207a97b51b8SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2208a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r) {
2209a97b51b8SMatthew G. Knepley           if (cone[r+2] == f) break;
2210a97b51b8SMatthew G. Knepley         }
2211a97b51b8SMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
2212a97b51b8SMatthew G. Knepley       }
2213a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2214a97b51b8SMatthew G. Knepley #if 1
2215a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2216a97b51b8SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2217a97b51b8SMatthew 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);
2218a97b51b8SMatthew G. Knepley       }
2219a97b51b8SMatthew G. Knepley #endif
2220a97b51b8SMatthew G. Knepley     }
2221a97b51b8SMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
2222a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
2223a97b51b8SMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
2224a97b51b8SMatthew G. Knepley       const PetscInt *cone;
2225a97b51b8SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
2226a97b51b8SMatthew G. Knepley 
2227a97b51b8SMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2228a97b51b8SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
2229a97b51b8SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
2230a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2231a97b51b8SMatthew G. Knepley #if 1
2232a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2233a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2234a97b51b8SMatthew 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);
2235a97b51b8SMatthew G. Knepley       }
2236a97b51b8SMatthew G. Knepley #endif
2237a97b51b8SMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
2238a97b51b8SMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
2239a97b51b8SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2240a97b51b8SMatthew G. Knepley #if 1
2241a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2242a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2243a97b51b8SMatthew 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);
2244a97b51b8SMatthew G. Knepley       }
2245a97b51b8SMatthew G. Knepley #endif
2246a97b51b8SMatthew G. Knepley     }
2247a97b51b8SMatthew G. Knepley     /* Old vertices have identical supports */
2248a97b51b8SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
2249a97b51b8SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
2250a97b51b8SMatthew G. Knepley       const PetscInt *support, *cone;
2251a97b51b8SMatthew G. Knepley       PetscInt        size, s;
2252a97b51b8SMatthew G. Knepley 
2253a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
2254a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
2255a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2256a97b51b8SMatthew G. Knepley         if (support[s] >= fMax) {
2257a97b51b8SMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax);
2258a97b51b8SMatthew G. Knepley         } else {
2259a97b51b8SMatthew G. Knepley           PetscInt r = 0;
2260a97b51b8SMatthew G. Knepley 
2261a97b51b8SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2262a97b51b8SMatthew G. Knepley           if (cone[1] == v) r = 1;
2263a97b51b8SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
2264a97b51b8SMatthew G. Knepley         }
2265a97b51b8SMatthew G. Knepley       }
2266a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2267a97b51b8SMatthew G. Knepley #if 1
2268a97b51b8SMatthew 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);
2269a97b51b8SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2270a97b51b8SMatthew 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);
2271a97b51b8SMatthew G. Knepley       }
2272a97b51b8SMatthew G. Knepley #endif
2273a97b51b8SMatthew G. Knepley     }
2274a97b51b8SMatthew G. Knepley     /* Face vertices have 2 + cells supports */
2275a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
2276a97b51b8SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
2277a97b51b8SMatthew G. Knepley       const PetscInt *cone, *support;
2278a97b51b8SMatthew G. Knepley       PetscInt        size, s;
2279a97b51b8SMatthew G. Knepley 
2280a97b51b8SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
2281a97b51b8SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2282a97b51b8SMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
2283a97b51b8SMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
2284a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2285a97b51b8SMatthew G. Knepley         PetscInt r = 0;
2286a97b51b8SMatthew G. Knepley 
2287a97b51b8SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2288a97b51b8SMatthew G. Knepley         if (support[s] >= cMax) {
2289a97b51b8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax);
2290a97b51b8SMatthew G. Knepley         } else {
2291a97b51b8SMatthew G. Knepley           if      (cone[1] == f) r = 1;
2292a97b51b8SMatthew G. Knepley           else if (cone[2] == f) r = 2;
2293a97b51b8SMatthew G. Knepley           else if (cone[3] == f) r = 3;
2294a97b51b8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r;
2295a97b51b8SMatthew G. Knepley         }
2296a97b51b8SMatthew G. Knepley       }
2297a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2298a97b51b8SMatthew G. Knepley #if 1
2299a97b51b8SMatthew 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);
2300a97b51b8SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
2301a97b51b8SMatthew 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);
2302a97b51b8SMatthew G. Knepley       }
2303a97b51b8SMatthew G. Knepley #endif
2304a97b51b8SMatthew G. Knepley     }
2305a97b51b8SMatthew G. Knepley     /* Cell vertices have 4 supports */
2306a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
2307a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
2308a97b51b8SMatthew G. Knepley       PetscInt       supportNew[4];
2309a97b51b8SMatthew G. Knepley 
2310a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2311a97b51b8SMatthew G. Knepley         supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
2312a97b51b8SMatthew G. Knepley       }
2313a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2314a97b51b8SMatthew G. Knepley     }
2315a97b51b8SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
2316a97b51b8SMatthew G. Knepley     break;
23179b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
2318b5da9499SMatthew G. Knepley     /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
2319b5da9499SMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
2320b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2321b5da9499SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
2322b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
2323b5da9499SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
2324b5da9499SMatthew G. Knepley 
2325b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2326b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2327b5da9499SMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
2328518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
2329b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2330518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
2331b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2332518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
2333b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2334b5da9499SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
2335b5da9499SMatthew G. Knepley       orntNew[3] = 0;
2336b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2337b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2338b5da9499SMatthew G. Knepley #if 1
2339b5da9499SMatthew 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);
2340b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2341b5da9499SMatthew 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);
2342b5da9499SMatthew G. Knepley       }
2343b5da9499SMatthew G. Knepley #endif
2344b5da9499SMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
2345518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
2346b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2347518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
2348b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2349b5da9499SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
2350b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2351518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
2352b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2353b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2354b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2355b5da9499SMatthew G. Knepley #if 1
2356b5da9499SMatthew 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);
2357b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2358b5da9499SMatthew 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);
2359b5da9499SMatthew G. Knepley       }
2360b5da9499SMatthew G. Knepley #endif
2361b5da9499SMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
2362518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
2363b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2364b5da9499SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
2365b5da9499SMatthew G. Knepley       orntNew[1] = 0;
2366518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
2367b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2368518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
2369b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2370b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2371b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2372b5da9499SMatthew G. Knepley #if 1
2373b5da9499SMatthew 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);
2374b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2375b5da9499SMatthew 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);
2376b5da9499SMatthew G. Knepley       }
2377b5da9499SMatthew G. Knepley #endif
2378b5da9499SMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
2379b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
2380b5da9499SMatthew G. Knepley       orntNew[0] = 0;
2381518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
2382b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2383518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
2384b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2385518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
2386b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2387b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2388b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2389b5da9499SMatthew G. Knepley #if 1
2390b5da9499SMatthew 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);
2391b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2392b5da9499SMatthew 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);
2393b5da9499SMatthew G. Knepley       }
2394b5da9499SMatthew G. Knepley #endif
23953fe31fa2SToby Isaac       /* A' tetrahedron: {c, d, a, f} */
2396b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
2397b5da9499SMatthew G. Knepley       orntNew[0] = -3;
2398fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
2399db2c6090SMatthew G. Knepley       orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0);
2400fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
2401fac4ab25SMatthew G. Knepley       orntNew[2] = 0;
2402fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
2403fac4ab25SMatthew G. Knepley       orntNew[3] = 2;
2404b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
2405b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
2406b5da9499SMatthew G. Knepley #if 1
2407b5da9499SMatthew 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);
2408b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2409b5da9499SMatthew 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);
2410b5da9499SMatthew G. Knepley       }
2411b5da9499SMatthew G. Knepley #endif
2412b5da9499SMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
2413b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
24143fe31fa2SToby Isaac       orntNew[0] = -2;
24153fe31fa2SToby Isaac       coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3;
24163fe31fa2SToby Isaac       orntNew[1] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 1)+1) : GetTetSomething_Static(ornt[3], 1);
24173fe31fa2SToby Isaac       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
2418b5da9499SMatthew G. Knepley       orntNew[2] = 0;
24193fe31fa2SToby Isaac       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
24203fe31fa2SToby Isaac       orntNew[3] = 0;
2421b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
2422b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
2423b5da9499SMatthew G. Knepley #if 1
2424b5da9499SMatthew 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);
2425b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2426b5da9499SMatthew 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);
2427b5da9499SMatthew G. Knepley       }
2428b5da9499SMatthew G. Knepley #endif
24293fe31fa2SToby Isaac       /* C' tetrahedron: {f, a, c, b} */
24303fe31fa2SToby Isaac       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
24313fe31fa2SToby Isaac       orntNew[0] = -2;
24323fe31fa2SToby Isaac       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
24333fe31fa2SToby Isaac       orntNew[1] = -2;
24343fe31fa2SToby Isaac       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
24353fe31fa2SToby Isaac       orntNew[2] = -1;
24363fe31fa2SToby Isaac       coneNew[3] = fStartNew + (cone[0] - fStart)*4 + 3;
24373fe31fa2SToby Isaac       orntNew[3] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2);
2438b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
2439b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
2440b5da9499SMatthew G. Knepley #if 1
2441b5da9499SMatthew 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);
2442b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2443b5da9499SMatthew 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);
2444b5da9499SMatthew G. Knepley       }
2445b5da9499SMatthew G. Knepley #endif
24463fe31fa2SToby Isaac       /* D' tetrahedron: {f, a, e, d} */
24473fe31fa2SToby Isaac       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
24483fe31fa2SToby Isaac       orntNew[0] = -2;
2449fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
24503fe31fa2SToby Isaac       orntNew[1] = -1;
24513fe31fa2SToby Isaac       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
24523fe31fa2SToby Isaac       orntNew[2] = -2;
24533fe31fa2SToby Isaac       coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3;
24543fe31fa2SToby Isaac       orntNew[3] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 1)+1) : GetTetSomething_Static(ornt[1], 1);
2455b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
2456b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
2457b5da9499SMatthew G. Knepley #if 1
2458b5da9499SMatthew 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);
2459b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2460b5da9499SMatthew 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);
2461b5da9499SMatthew G. Knepley       }
2462b5da9499SMatthew G. Knepley #endif
2463b5da9499SMatthew G. Knepley     }
2464b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
2465b5da9499SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2466854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
2467b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
2468b5da9499SMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
2469b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
2470b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
2471b5da9499SMatthew G. Knepley 
2472b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2473b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
2474b5da9499SMatthew G. Knepley       /* A triangle */
2475b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
2476b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2477b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
2478b5da9499SMatthew G. Knepley       orntNew[1] = -2;
2479b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
2480b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2481b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2482b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2483b5da9499SMatthew G. Knepley #if 1
2484b5da9499SMatthew 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);
2485b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2486b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2487b5da9499SMatthew G. Knepley       }
2488b5da9499SMatthew G. Knepley #endif
2489b5da9499SMatthew G. Knepley       /* B triangle */
2490b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
2491b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2492b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
2493b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2494b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
2495b5da9499SMatthew G. Knepley       orntNew[2] = -2;
2496b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2497b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2498b5da9499SMatthew G. Knepley #if 1
2499b5da9499SMatthew 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);
2500b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2501b5da9499SMatthew 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);
2502b5da9499SMatthew G. Knepley       }
2503b5da9499SMatthew G. Knepley #endif
2504b5da9499SMatthew G. Knepley       /* C triangle */
2505b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
2506b5da9499SMatthew G. Knepley       orntNew[0] = -2;
2507b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
2508b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2509b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
2510b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2511b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2512b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2513b5da9499SMatthew G. Knepley #if 1
2514b5da9499SMatthew 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);
2515b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2516b5da9499SMatthew 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);
2517b5da9499SMatthew G. Knepley       }
2518b5da9499SMatthew G. Knepley #endif
2519b5da9499SMatthew G. Knepley       /* D triangle */
2520b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
2521b5da9499SMatthew G. Knepley       orntNew[0] = 0;
2522b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
2523b5da9499SMatthew G. Knepley       orntNew[1] = 0;
2524b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
2525b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2526b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2527b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2528b5da9499SMatthew G. Knepley #if 1
2529b5da9499SMatthew 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);
2530b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2531b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2532b5da9499SMatthew G. Knepley       }
2533b5da9499SMatthew G. Knepley #endif
2534b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2535b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2536b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2537b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2538219f7b90SMatthew G. Knepley           PetscInt subf;
2539b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2540b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2541b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2542b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
2543b5da9499SMatthew G. Knepley             if (cone[c] == f) break;
2544b5da9499SMatthew G. Knepley           }
2545219f7b90SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
2546219f7b90SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
2547b5da9499SMatthew G. Knepley         }
2548b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
2549b5da9499SMatthew G. Knepley #if 1
25509ddff745SMatthew 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);
2551b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2552b5da9499SMatthew 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);
2553b5da9499SMatthew G. Knepley         }
2554b5da9499SMatthew G. Knepley #endif
2555b5da9499SMatthew G. Knepley       }
2556b5da9499SMatthew G. Knepley     }
2557b5da9499SMatthew G. Knepley     /* Interior faces have 3 edges and 2 cells */
2558b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2559b5da9499SMatthew G. Knepley       PetscInt        newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8;
2560b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
2561b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
2562b5da9499SMatthew G. Knepley       PetscInt        supportNew[2];
2563b5da9499SMatthew G. Knepley 
2564b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2565b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2566b5da9499SMatthew G. Knepley       /* Face A: {c, a, d} */
25674bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
2568b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
25694bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
2570b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
25714bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2);
2572b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
2573b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2574b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2575b5da9499SMatthew G. Knepley #if 1
2576b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2577b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2578b5da9499SMatthew 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);
2579b5da9499SMatthew G. Knepley       }
2580b5da9499SMatthew G. Knepley #endif
2581b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
2582b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
2583b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2584b5da9499SMatthew G. Knepley #if 1
2585b5da9499SMatthew G. 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 < 2; ++p) {
2587b5da9499SMatthew 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);
2588b5da9499SMatthew G. Knepley       }
2589b5da9499SMatthew G. Knepley #endif
2590b5da9499SMatthew G. Knepley       ++newp;
2591b5da9499SMatthew G. Knepley       /* Face B: {a, b, e} */
25924bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
2593b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
25944bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0);
2595b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
25964bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
2597b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
2598b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2599b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2600b5da9499SMatthew G. Knepley #if 1
26014bb260e2SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2602b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2603b5da9499SMatthew 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);
2604b5da9499SMatthew G. Knepley       }
2605b5da9499SMatthew G. Knepley #endif
2606b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
2607b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
2608b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);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 < 2; ++p) {
2612b5da9499SMatthew 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);
2613b5da9499SMatthew G. Knepley       }
2614b5da9499SMatthew G. Knepley #endif
2615b5da9499SMatthew G. Knepley       ++newp;
2616b5da9499SMatthew G. Knepley       /* Face C: {c, f, b} */
26174bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
2618b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
26194bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
2620b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
26214bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1);
2622b5da9499SMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
2623b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2624b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2625b5da9499SMatthew G. Knepley #if 1
2626b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2627b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2628b5da9499SMatthew 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);
2629b5da9499SMatthew G. Knepley       }
2630b5da9499SMatthew G. Knepley #endif
2631b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
2632b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2633b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);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 < 2; ++p) {
2637b5da9499SMatthew 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);
2638b5da9499SMatthew G. Knepley       }
2639b5da9499SMatthew G. Knepley #endif
2640b5da9499SMatthew G. Knepley       ++newp;
2641b5da9499SMatthew G. Knepley       /* Face D: {d, e, f} */
26424bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0);
2643b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
26444bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
2645b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
26464bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
2647b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
2648b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2649b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2650b5da9499SMatthew G. Knepley #if 1
2651b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2652b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2653b5da9499SMatthew 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);
2654b5da9499SMatthew G. Knepley       }
2655b5da9499SMatthew G. Knepley #endif
2656b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
2657b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2658b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);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 < 2; ++p) {
2662b5da9499SMatthew 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);
2663b5da9499SMatthew G. Knepley       }
2664b5da9499SMatthew G. Knepley #endif
2665b5da9499SMatthew G. Knepley       ++newp;
2666b5da9499SMatthew G. Knepley       /* Face E: {d, f, a} */
26674bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
2668b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
2669b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
26704bb260e2SMatthew G. Knepley       orntNew[1] = -2;
26714bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
2672b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
2673b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2674b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2675b5da9499SMatthew G. Knepley #if 1
2676b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2677b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2678b5da9499SMatthew 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);
2679b5da9499SMatthew G. Knepley       }
2680b5da9499SMatthew G. Knepley #endif
2681b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
2682b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2683b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);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 < 2; ++p) {
2687b5da9499SMatthew 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);
2688b5da9499SMatthew G. Knepley       }
2689b5da9499SMatthew G. Knepley #endif
2690b5da9499SMatthew G. Knepley       ++newp;
2691b5da9499SMatthew G. Knepley       /* Face F: {c, a, f} */
26924bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
2693b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
2694b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
26954bb260e2SMatthew G. Knepley       orntNew[1] = 0;
26964bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
26972baf2947SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
2698b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2699b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2700b5da9499SMatthew G. Knepley #if 1
2701b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2702b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2703b5da9499SMatthew 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);
2704b5da9499SMatthew G. Knepley       }
2705b5da9499SMatthew G. Knepley #endif
2706b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
2707b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2708b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);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 < 2; ++p) {
2712b5da9499SMatthew 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);
2713b5da9499SMatthew G. Knepley       }
2714b5da9499SMatthew G. Knepley #endif
2715b5da9499SMatthew G. Knepley       ++newp;
2716b5da9499SMatthew G. Knepley       /* Face G: {e, a, f} */
27174bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
2718b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
2719b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2720fac4ab25SMatthew G. Knepley       orntNew[1] = 0;
27214bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
2722b5da9499SMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
2723b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2724b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2725b5da9499SMatthew G. Knepley #if 1
2726b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2727b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2728b5da9499SMatthew 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);
2729b5da9499SMatthew G. Knepley       }
2730b5da9499SMatthew G. Knepley #endif
2731b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
2732b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2733b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);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 < 2; ++p) {
2737b5da9499SMatthew 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);
2738b5da9499SMatthew G. Knepley       }
2739b5da9499SMatthew G. Knepley #endif
2740b5da9499SMatthew G. Knepley       ++newp;
2741b5da9499SMatthew G. Knepley       /* Face H: {a, b, f} */
27424bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
2743b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
27444bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
2745b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
2746b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
27474bb260e2SMatthew G. Knepley       orntNew[2] = -2;
2748b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2749b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2750b5da9499SMatthew G. Knepley #if 1
2751b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2752b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2753b5da9499SMatthew 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);
2754b5da9499SMatthew G. Knepley       }
2755b5da9499SMatthew G. Knepley #endif
2756b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
2757b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2758b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2759b5da9499SMatthew G. Knepley #if 1
2760b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2761b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2762b5da9499SMatthew 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);
2763b5da9499SMatthew G. Knepley       }
2764b5da9499SMatthew G. Knepley #endif
2765b5da9499SMatthew G. Knepley       ++newp;
2766b5da9499SMatthew G. Knepley     }
2767b5da9499SMatthew G. Knepley     /* Split Edges have 2 vertices and the same faces as the parent */
2768b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
2769b5da9499SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
2770b5da9499SMatthew G. Knepley 
2771b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
2772b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
2773b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
2774b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
2775b5da9499SMatthew G. Knepley 
2776b5da9499SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
2777b5da9499SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
2778b5da9499SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
2779b5da9499SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
2780b5da9499SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2781b5da9499SMatthew G. Knepley #if 1
2782b5da9499SMatthew 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);
2783b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2784b5da9499SMatthew 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);
2785b5da9499SMatthew G. Knepley         }
2786b5da9499SMatthew G. Knepley #endif
2787b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
2788b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
2789b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2790b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2791b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2792b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2793b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
2794b5da9499SMatthew G. Knepley             if (cone[c] == e) break;
2795b5da9499SMatthew G. Knepley           }
2796b5da9499SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
2797b5da9499SMatthew G. Knepley         }
2798b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2799b5da9499SMatthew G. Knepley #if 1
2800b5da9499SMatthew 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);
2801b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2802b5da9499SMatthew 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);
2803b5da9499SMatthew G. Knepley         }
2804b5da9499SMatthew G. Knepley #endif
2805b5da9499SMatthew G. Knepley       }
2806b5da9499SMatthew G. Knepley     }
280786f0afeeSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
2808b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
2809b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
2810b5da9499SMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
2811b5da9499SMatthew G. Knepley 
2812b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2813b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2814b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
2815b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
2816b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
2817b5da9499SMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
2818b5da9499SMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
2819b5da9499SMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
2820b5da9499SMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
2821b5da9499SMatthew G. Knepley 
2822b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2823b5da9499SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
2824b5da9499SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
2825b5da9499SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2826b5da9499SMatthew G. Knepley #if 1
2827b5da9499SMatthew 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);
2828b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2829b5da9499SMatthew 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);
2830b5da9499SMatthew G. Knepley         }
2831b5da9499SMatthew G. Knepley #endif
2832b5da9499SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
2833b5da9499SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
2834b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2835b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2836b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2837b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2838b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
283986f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
28409ddff745SMatthew G. Knepley           er = GetTetSomethingInverse_Static(ornt[c], r);
2841b5da9499SMatthew G. Knepley           if (er == eint[c]) {
2842b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
2843b5da9499SMatthew G. Knepley           } else {
2844b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
2845b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
2846b5da9499SMatthew G. Knepley           }
2847b5da9499SMatthew G. Knepley         }
2848b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2849b5da9499SMatthew G. Knepley #if 1
2850b5da9499SMatthew 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);
2851b5da9499SMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
2852b5da9499SMatthew 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);
2853b5da9499SMatthew G. Knepley         }
2854b5da9499SMatthew G. Knepley #endif
2855b5da9499SMatthew G. Knepley       }
2856b5da9499SMatthew G. Knepley     }
2857b5da9499SMatthew G. Knepley     /* Interior edges have 2 vertices and 4 faces */
2858b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2859b5da9499SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2860b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
28614a40f731SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
2862b5da9499SMatthew G. Knepley 
2863b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2864b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2865b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
286642525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
2867b5da9499SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2868b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
286942525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
2870b5da9499SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2871b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2872b5da9499SMatthew G. Knepley #if 1
2873b5da9499SMatthew 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);
2874b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2875b5da9499SMatthew 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);
2876b5da9499SMatthew G. Knepley       }
2877b5da9499SMatthew G. Knepley #endif
2878b5da9499SMatthew G. Knepley       supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
2879b5da9499SMatthew G. Knepley       supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
2880b5da9499SMatthew G. Knepley       supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
2881b5da9499SMatthew G. Knepley       supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
2882b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2883b5da9499SMatthew G. Knepley #if 1
2884b5da9499SMatthew 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);
2885b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2886b5da9499SMatthew 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);
2887b5da9499SMatthew G. Knepley       }
2888b5da9499SMatthew G. Knepley #endif
2889b5da9499SMatthew G. Knepley     }
2890b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
2891b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
2892b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
2893b5da9499SMatthew G. Knepley       const PetscInt *support, *cone;
2894b5da9499SMatthew G. Knepley       PetscInt        size, s;
2895b5da9499SMatthew G. Knepley 
2896b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
2897b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
2898b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2899b5da9499SMatthew G. Knepley         PetscInt r = 0;
2900b5da9499SMatthew G. Knepley 
2901b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2902b5da9499SMatthew G. Knepley         if (cone[1] == v) r = 1;
2903b5da9499SMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
2904b5da9499SMatthew G. Knepley       }
2905b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2906b5da9499SMatthew G. Knepley #if 1
2907b5da9499SMatthew 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);
2908b5da9499SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2909b5da9499SMatthew 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);
2910b5da9499SMatthew G. Knepley       }
2911b5da9499SMatthew G. Knepley #endif
2912b5da9499SMatthew G. Knepley     }
2913b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + face*2 + 0/1 supports */
2914b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
2915b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
2916b5da9499SMatthew G. Knepley       const PetscInt *cone, *support;
2917b5da9499SMatthew G. Knepley       PetscInt       *star = NULL, starSize, cellSize = 0, coneSize, size, s;
2918b5da9499SMatthew G. Knepley 
2919b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
2920b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
2921b5da9499SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
2922b5da9499SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
2923b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2924b5da9499SMatthew G. Knepley         PetscInt r = 0;
2925b5da9499SMatthew G. Knepley 
2926b5da9499SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2927b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2928b5da9499SMatthew G. Knepley         for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
2929b5da9499SMatthew G. Knepley         supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
2930b5da9499SMatthew G. Knepley         supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
2931b5da9499SMatthew G. Knepley       }
2932b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
2933b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
2934b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
2935b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
2936b5da9499SMatthew G. Knepley 
2937b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
2938b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
2939b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
2940b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
2941b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
294242525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
2943b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
2944b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
2945b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
294642525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
294742525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
2948b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);}
2949b5da9499SMatthew G. Knepley         }
2950b5da9499SMatthew G. Knepley       }
2951b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
2952b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2953b5da9499SMatthew G. Knepley #if 1
2954b5da9499SMatthew 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);
2955b5da9499SMatthew G. Knepley       for (p = 0; p < 2+size*2+cellSize; ++p) {
2956b5da9499SMatthew 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);
2957b5da9499SMatthew G. Knepley       }
2958b5da9499SMatthew G. Knepley #endif
2959b5da9499SMatthew G. Knepley     }
2960b5da9499SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
2961b5da9499SMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
2962b5da9499SMatthew G. Knepley     break;
29639b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
29646ce3c06aSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
29656ce3c06aSMatthew G. Knepley     /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
29666ce3c06aSMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
29676ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
29686ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
29696ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
29706ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
29716ce3c06aSMatthew G. Knepley 
29726ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
29736ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
29746ce3c06aSMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
29756ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
29766ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
29776ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
29786ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
29796ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
29806ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
29816ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
29826ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
29836ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
29846ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
29856ce3c06aSMatthew G. Knepley #if 1
29866ce3c06aSMatthew 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);
29876ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
29886ce3c06aSMatthew 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);
29896ce3c06aSMatthew G. Knepley       }
29906ce3c06aSMatthew G. Knepley #endif
29916ce3c06aSMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
29926ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
29936ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
29946ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
29956ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
29966ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
29976ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
29986ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
29996ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
30006ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
30016ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
30026ce3c06aSMatthew G. Knepley #if 1
30036ce3c06aSMatthew 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);
30046ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
30056ce3c06aSMatthew 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);
30066ce3c06aSMatthew G. Knepley       }
30076ce3c06aSMatthew G. Knepley #endif
30086ce3c06aSMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
30096ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
30106ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
30116ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
30126ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
30136ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
30146ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
30156ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
30166ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
30176ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
30186ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
30196ce3c06aSMatthew G. Knepley #if 1
30206ce3c06aSMatthew 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);
30216ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
30226ce3c06aSMatthew 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);
30236ce3c06aSMatthew G. Knepley       }
30246ce3c06aSMatthew G. Knepley #endif
30256ce3c06aSMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
30266ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
30276ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
30286ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
30296ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
30306ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
30316ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
30326ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
30336ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
30346ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
30356ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
30366ce3c06aSMatthew G. Knepley #if 1
30376ce3c06aSMatthew 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);
30386ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
30396ce3c06aSMatthew 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);
30406ce3c06aSMatthew G. Knepley       }
30416ce3c06aSMatthew G. Knepley #endif
30426ce3c06aSMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
30436ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
30446ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
30459ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
30469ddff745SMatthew G. Knepley       orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0);
30479ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
30489ddff745SMatthew G. Knepley       orntNew[2] = 0;
30499ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
30509ddff745SMatthew G. Knepley       orntNew[3] = 2;
30516ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
30526ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
30536ce3c06aSMatthew G. Knepley #if 1
30546ce3c06aSMatthew 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);
30556ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
30566ce3c06aSMatthew 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);
30576ce3c06aSMatthew G. Knepley       }
30586ce3c06aSMatthew G. Knepley #endif
30596ce3c06aSMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
30606ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
30616ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
30629ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
30639ddff745SMatthew G. Knepley       orntNew[1] = 1;
30649ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
30656ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
30669ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
30679ddff745SMatthew G. Knepley       orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0);
30686ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
30696ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
30706ce3c06aSMatthew G. Knepley #if 1
30716ce3c06aSMatthew 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);
30726ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
30736ce3c06aSMatthew 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);
30746ce3c06aSMatthew G. Knepley       }
30756ce3c06aSMatthew G. Knepley #endif
30766ce3c06aSMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
30776ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
30786ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
30799ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
30809ddff745SMatthew G. Knepley       orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2);
30819ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
30829ddff745SMatthew G. Knepley       orntNew[2] = -3;
30839ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
30849ddff745SMatthew G. Knepley       orntNew[3] = -2;
30856ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
30866ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
30876ce3c06aSMatthew G. Knepley #if 1
30886ce3c06aSMatthew 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);
30896ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
30906ce3c06aSMatthew 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);
30916ce3c06aSMatthew G. Knepley       }
30926ce3c06aSMatthew G. Knepley #endif
30936ce3c06aSMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
30946ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
30956ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
30969ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
30976ce3c06aSMatthew G. Knepley       orntNew[1] = -3;
30989ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
30999ddff745SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0);
31009ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
31019ddff745SMatthew G. Knepley       orntNew[3] = -3;
31026ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
31036ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
31046ce3c06aSMatthew G. Knepley #if 1
31056ce3c06aSMatthew 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);
31066ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
31076ce3c06aSMatthew 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);
31086ce3c06aSMatthew G. Knepley       }
31096ce3c06aSMatthew G. Knepley #endif
31106ce3c06aSMatthew G. Knepley     }
31116ce3c06aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
31126ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
31136ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4;
3114d3a1cc75SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
31153b61eb6dSMatthew G. Knepley       PetscInt        coneNew[5], orntNew[5], o, of, i;
31166ce3c06aSMatthew G. Knepley 
31176ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
31186ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
3119d3a1cc75SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
3120084f9c62SMatthew G. Knepley       o = ornt[0] < 0 ? -1 : 1;
31216ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
31226ce3c06aSMatthew G. Knepley         coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r);
31236ce3c06aSMatthew G. Knepley         orntNew[0] = ornt[0];
31246ce3c06aSMatthew G. Knepley         coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r);
31256ce3c06aSMatthew G. Knepley         orntNew[1] = ornt[1];
3126084f9c62SMatthew G. Knepley         of = fornt[GetTriEdge_Static(ornt[0], r)]       < 0 ? -1 : 1;
31273b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], r)       + 2;
31283b61eb6dSMatthew 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);
31293b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
31303b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2;
31313b61eb6dSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r);
31323b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
31333b61eb6dSMatthew G. Knepley         of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1;
31343b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2;
31353b61eb6dSMatthew 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);
31363b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
31376ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
31386ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
31396ce3c06aSMatthew G. Knepley #if 1
31406ce3c06aSMatthew 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);
31416ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
31426ce3c06aSMatthew 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);
31436ce3c06aSMatthew G. Knepley         }
31446ce3c06aSMatthew G. Knepley         for (p = 2; p < 5; ++p) {
31456ce3c06aSMatthew 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);
31466ce3c06aSMatthew G. Knepley         }
31476ce3c06aSMatthew G. Knepley #endif
31486ce3c06aSMatthew G. Knepley       }
31496ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3;
31506ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
31516ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3;
31526ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
31533b61eb6dSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1;
31546ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
31553b61eb6dSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2;
31566ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
31573b61eb6dSMatthew G. Knepley       coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0;
31586ce3c06aSMatthew G. Knepley       orntNew[4] = 0;
31596ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
31606ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
31616ce3c06aSMatthew G. Knepley #if 1
31626ce3c06aSMatthew 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);
31636ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
31646ce3c06aSMatthew 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);
31656ce3c06aSMatthew G. Knepley       }
31666ce3c06aSMatthew G. Knepley       for (p = 2; p < 5; ++p) {
31676ce3c06aSMatthew 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);
31686ce3c06aSMatthew G. Knepley       }
31696ce3c06aSMatthew G. Knepley #endif
31706ce3c06aSMatthew G. Knepley     }
31716ce3c06aSMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
31726ce3c06aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
3173854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
31746ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
31756ce3c06aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
31766ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
31776ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
31786ce3c06aSMatthew G. Knepley 
31796ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
31806ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
31816ce3c06aSMatthew G. Knepley       /* A triangle */
31826ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
31836ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
31846ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
31856ce3c06aSMatthew G. Knepley       orntNew[1] = -2;
31866ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
31876ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
31886ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
31896ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
31906ce3c06aSMatthew G. Knepley #if 1
31916ce3c06aSMatthew 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);
31926ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
31936ce3c06aSMatthew 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);
31946ce3c06aSMatthew G. Knepley       }
31956ce3c06aSMatthew G. Knepley #endif
31966ce3c06aSMatthew G. Knepley       /* B triangle */
31976ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
31986ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
31996ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
32006ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
32016ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
32026ce3c06aSMatthew G. Knepley       orntNew[2] = -2;
32036ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
32046ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
32056ce3c06aSMatthew G. Knepley #if 1
32066ce3c06aSMatthew 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);
32076ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
32086ce3c06aSMatthew 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);
32096ce3c06aSMatthew G. Knepley       }
32106ce3c06aSMatthew G. Knepley #endif
32116ce3c06aSMatthew G. Knepley       /* C triangle */
32126ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
32136ce3c06aSMatthew G. Knepley       orntNew[0] = -2;
32146ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
32156ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
32166ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
32176ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
32186ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
32196ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
32206ce3c06aSMatthew G. Knepley #if 1
32216ce3c06aSMatthew 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);
32226ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
32236ce3c06aSMatthew 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);
32246ce3c06aSMatthew G. Knepley       }
32256ce3c06aSMatthew G. Knepley #endif
32266ce3c06aSMatthew G. Knepley       /* D triangle */
32276ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
32286ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
32296ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
32306ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
32316ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
32326ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
32336ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
32346ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
32356ce3c06aSMatthew G. Knepley #if 1
32366ce3c06aSMatthew 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);
32376ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
32386ce3c06aSMatthew 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);
32396ce3c06aSMatthew G. Knepley       }
32406ce3c06aSMatthew G. Knepley #endif
32416ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
32426ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
32436ce3c06aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
32446ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
32459ddff745SMatthew G. Knepley           PetscInt subf;
32466ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
32476ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
32486ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
32496ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
32506ce3c06aSMatthew G. Knepley             if (cone[c] == f) break;
32516ce3c06aSMatthew G. Knepley           }
32529ddff745SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
32536ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
32549ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
32556ce3c06aSMatthew G. Knepley           } else {
32569ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf);
32576ce3c06aSMatthew G. Knepley           }
32586ce3c06aSMatthew G. Knepley         }
32596ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
32606ce3c06aSMatthew G. Knepley #if 1
32619ddff745SMatthew 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);
32626ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
32636ce3c06aSMatthew 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);
32646ce3c06aSMatthew G. Knepley         }
32656ce3c06aSMatthew G. Knepley #endif
32666ce3c06aSMatthew G. Knepley       }
32676ce3c06aSMatthew G. Knepley     }
32686ce3c06aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
32696ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
32706ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8;
32716ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
32726ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
32736ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
32746ce3c06aSMatthew G. Knepley 
32756ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
32766ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
32776ce3c06aSMatthew G. Knepley       /* Face A: {c, a, d} */
32789ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
32796ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
32809ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
32816ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
32829ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2);
32836ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
32846ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
32856ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32866ce3c06aSMatthew G. Knepley #if 1
32876ce3c06aSMatthew 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);
32886ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
32896ce3c06aSMatthew 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);
32906ce3c06aSMatthew G. Knepley       }
32916ce3c06aSMatthew G. Knepley #endif
32926ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
32936ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
32946ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
32956ce3c06aSMatthew G. Knepley #if 1
32966ce3c06aSMatthew 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);
32976ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
32986ce3c06aSMatthew 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);
32996ce3c06aSMatthew G. Knepley       }
33006ce3c06aSMatthew G. Knepley #endif
33016ce3c06aSMatthew G. Knepley       ++newp;
33026ce3c06aSMatthew G. Knepley       /* Face B: {a, b, e} */
33039ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
33046ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
33059ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0);
33066ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
33079ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
33086ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
33096ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
33106ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
33116ce3c06aSMatthew G. Knepley #if 1
33126ce3c06aSMatthew 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);
33136ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
33146ce3c06aSMatthew 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);
33156ce3c06aSMatthew G. Knepley       }
33166ce3c06aSMatthew G. Knepley #endif
33176ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
33186ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
33196ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);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 < 2; ++p) {
33236ce3c06aSMatthew 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);
33246ce3c06aSMatthew G. Knepley       }
33256ce3c06aSMatthew G. Knepley #endif
33266ce3c06aSMatthew G. Knepley       ++newp;
33276ce3c06aSMatthew G. Knepley       /* Face C: {c, f, b} */
33289ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
33296ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
33309ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
33316ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
33329ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1);
33336ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
33346ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
33356ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
33366ce3c06aSMatthew G. Knepley #if 1
33376ce3c06aSMatthew 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);
33386ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
33396ce3c06aSMatthew 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);
33406ce3c06aSMatthew G. Knepley       }
33416ce3c06aSMatthew G. Knepley #endif
33426ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
33436ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
33446ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);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 < 2; ++p) {
33486ce3c06aSMatthew 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);
33496ce3c06aSMatthew G. Knepley       }
33506ce3c06aSMatthew G. Knepley #endif
33516ce3c06aSMatthew G. Knepley       ++newp;
33526ce3c06aSMatthew G. Knepley       /* Face D: {d, e, f} */
33539ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0);
33546ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
33559ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
33566ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
33579ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
33586ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
33596ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
33606ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
33616ce3c06aSMatthew G. Knepley #if 1
33626ce3c06aSMatthew 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);
33636ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
33646ce3c06aSMatthew 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);
33656ce3c06aSMatthew G. Knepley       }
33666ce3c06aSMatthew G. Knepley #endif
33676ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
33686ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
33696ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);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 < 2; ++p) {
33736ce3c06aSMatthew 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);
33746ce3c06aSMatthew G. Knepley       }
33756ce3c06aSMatthew G. Knepley #endif
33766ce3c06aSMatthew G. Knepley       ++newp;
33776ce3c06aSMatthew G. Knepley       /* Face E: {d, f, a} */
33789ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
33796ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
33806ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
33819ddff745SMatthew G. Knepley       orntNew[1] = -2;
33829ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
33836ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
33846ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
33856ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
33866ce3c06aSMatthew G. Knepley #if 1
33876ce3c06aSMatthew 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);
33886ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
33896ce3c06aSMatthew 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);
33906ce3c06aSMatthew G. Knepley       }
33916ce3c06aSMatthew G. Knepley #endif
33926ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
33936ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
33946ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);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 < 2; ++p) {
33986ce3c06aSMatthew 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);
33996ce3c06aSMatthew G. Knepley       }
34006ce3c06aSMatthew G. Knepley #endif
34016ce3c06aSMatthew G. Knepley       ++newp;
34026ce3c06aSMatthew G. Knepley       /* Face F: {c, a, f} */
34039ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
34046ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
34056ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
34069ddff745SMatthew G. Knepley       orntNew[1] = 0;
34079ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
34089ddff745SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
34096ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
34106ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
34116ce3c06aSMatthew G. Knepley #if 1
34126ce3c06aSMatthew 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);
34136ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
34146ce3c06aSMatthew 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);
34156ce3c06aSMatthew G. Knepley       }
34166ce3c06aSMatthew G. Knepley #endif
34176ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
34186ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
34196ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);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 < 2; ++p) {
34236ce3c06aSMatthew 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);
34246ce3c06aSMatthew G. Knepley       }
34256ce3c06aSMatthew G. Knepley #endif
34266ce3c06aSMatthew G. Knepley       ++newp;
34276ce3c06aSMatthew G. Knepley       /* Face G: {e, a, f} */
34289ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
34296ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
34306ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
34319ddff745SMatthew G. Knepley       orntNew[1] = 0;
34329ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
34336ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
34346ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
34356ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
34366ce3c06aSMatthew G. Knepley #if 1
34376ce3c06aSMatthew 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);
34386ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
34396ce3c06aSMatthew 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);
34406ce3c06aSMatthew G. Knepley       }
34416ce3c06aSMatthew G. Knepley #endif
34426ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
34436ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
34446ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);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 < 2; ++p) {
34486ce3c06aSMatthew 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);
34496ce3c06aSMatthew G. Knepley       }
34506ce3c06aSMatthew G. Knepley #endif
34516ce3c06aSMatthew G. Knepley       ++newp;
34526ce3c06aSMatthew G. Knepley       /* Face H: {a, b, f} */
34539ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
34546ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
34559ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
34566ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
34576ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
34589ddff745SMatthew G. Knepley       orntNew[2] = -2;
34596ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
34606ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
34616ce3c06aSMatthew G. Knepley #if 1
34626ce3c06aSMatthew 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);
34636ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
34646ce3c06aSMatthew 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);
34656ce3c06aSMatthew G. Knepley       }
34666ce3c06aSMatthew G. Knepley #endif
34676ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
34686ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
34696ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
34706ce3c06aSMatthew G. Knepley #if 1
34716ce3c06aSMatthew 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);
34726ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
34736ce3c06aSMatthew 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);
34746ce3c06aSMatthew G. Knepley       }
34756ce3c06aSMatthew G. Knepley #endif
34766ce3c06aSMatthew G. Knepley       ++newp;
34776ce3c06aSMatthew G. Knepley     }
34786ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
34796ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
34806ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
34816ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
34826ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
34836ce3c06aSMatthew G. Knepley 
34846ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
34856ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
34866ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
34876ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
34886ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
34896ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
34906ce3c06aSMatthew G. Knepley 
34916ce3c06aSMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
34926ce3c06aSMatthew G. Knepley         orntNew[0]   = ornt[0];
34936ce3c06aSMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
34946ce3c06aSMatthew G. Knepley         orntNew[1]   = ornt[1];
34956ce3c06aSMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax);
34966ce3c06aSMatthew G. Knepley         orntNew[2+r] = 0;
34976ce3c06aSMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd      - eMax) + (f - fMax);
34986ce3c06aSMatthew G. Knepley         orntNew[3-r] = 0;
34996ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
35006ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
35016ce3c06aSMatthew G. Knepley #if 1
35026ce3c06aSMatthew 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);
35036ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
35046ce3c06aSMatthew 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);
35056ce3c06aSMatthew G. Knepley         }
35066ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
35076ce3c06aSMatthew 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);
35086ce3c06aSMatthew G. Knepley         }
35096ce3c06aSMatthew G. Knepley #endif
35106ce3c06aSMatthew G. Knepley         for (s = 0; s < size; ++s) {
3511d3a1cc75SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
3512084f9c62SMatthew G. Knepley           PetscInt        o, of;
35136ce3c06aSMatthew G. Knepley 
35146ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
35156ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
3516084f9c62SMatthew G. Knepley           o = orntCell[0] < 0 ? -1 : 1;
35176ce3c06aSMatthew G. Knepley           for (c = 2; c < 5; ++c) if (coneCell[c] == f) break;
35186ce3c06aSMatthew 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]);
3519d3a1cc75SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
3520084f9c62SMatthew G. Knepley           of = fornt[c-2] < 0 ? -1 : 1;
3521084f9c62SMatthew 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;
35226ce3c06aSMatthew G. Knepley         }
35236ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
35246ce3c06aSMatthew G. Knepley #if 1
35256ce3c06aSMatthew 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);
35266ce3c06aSMatthew G. Knepley         for (p = 0; p < size; ++p) {
35276ce3c06aSMatthew 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);
35286ce3c06aSMatthew G. Knepley         }
35296ce3c06aSMatthew G. Knepley #endif
35306ce3c06aSMatthew G. Knepley       }
35316ce3c06aSMatthew G. Knepley     }
35326ce3c06aSMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
35336ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
35346ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3;
35356ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
35366ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
35376ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
35386ce3c06aSMatthew G. Knepley 
35396ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
35406ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
35416ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
3542b598a9d5SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3;
35436ce3c06aSMatthew G. Knepley         orntNew[0] = 0;
3544b598a9d5SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3;
35456ce3c06aSMatthew G. Knepley         orntNew[1] = 0;
3546b598a9d5SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax);
35476ce3c06aSMatthew G. Knepley         orntNew[2] = 0;
3548b598a9d5SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r]       - fMax);
35496ce3c06aSMatthew G. Knepley         orntNew[3] = 0;
35506ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
35516ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
35526ce3c06aSMatthew G. Knepley #if 1
35536ce3c06aSMatthew 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);
35546ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
35556ce3c06aSMatthew 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);
35566ce3c06aSMatthew G. Knepley         }
35576ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
35586ce3c06aSMatthew 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);
35596ce3c06aSMatthew G. Knepley         }
35606ce3c06aSMatthew G. Knepley #endif
35616ce3c06aSMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r);
35626ce3c06aSMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3;
35636ce3c06aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
35646ce3c06aSMatthew G. Knepley #if 1
35656ce3c06aSMatthew 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);
35666ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
35676ce3c06aSMatthew 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);
35686ce3c06aSMatthew G. Knepley         }
35696ce3c06aSMatthew G. Knepley #endif
35706ce3c06aSMatthew G. Knepley       }
35716ce3c06aSMatthew G. Knepley     }
35726ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
35736ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
35746ce3c06aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
35756ce3c06aSMatthew G. Knepley 
35766ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
35776ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
35786ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
35796ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
35806ce3c06aSMatthew G. Knepley 
35816ce3c06aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
35826ce3c06aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
35836ce3c06aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
35846ce3c06aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
35856ce3c06aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
35866ce3c06aSMatthew G. Knepley #if 1
35876ce3c06aSMatthew 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);
35886ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
35896ce3c06aSMatthew 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);
35906ce3c06aSMatthew G. Knepley         }
35916ce3c06aSMatthew G. Knepley #endif
35926ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
35936ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
35946ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
35956ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
35966ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
35976ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
35986ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == e) break;
35996ce3c06aSMatthew G. Knepley           if (support[s] < fMax) {
36006ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
36016ce3c06aSMatthew G. Knepley           } else {
36026ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
36036ce3c06aSMatthew G. Knepley           }
36046ce3c06aSMatthew G. Knepley         }
36056ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
36066ce3c06aSMatthew G. Knepley #if 1
36076ce3c06aSMatthew 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);
36086ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
36096ce3c06aSMatthew 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);
36106ce3c06aSMatthew G. Knepley         }
36116ce3c06aSMatthew G. Knepley #endif
36126ce3c06aSMatthew G. Knepley       }
36136ce3c06aSMatthew G. Knepley     }
36146ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
36156ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
36166ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
36176ce3c06aSMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
36186ce3c06aSMatthew G. Knepley 
36196ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
36206ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
36216ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
36226ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
36236ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
36246ce3c06aSMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
36256ce3c06aSMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
36266ce3c06aSMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
36276ce3c06aSMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
36286ce3c06aSMatthew G. Knepley 
36296ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
36306ce3c06aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
36316ce3c06aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
36326ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
36336ce3c06aSMatthew G. Knepley #if 1
36346ce3c06aSMatthew 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);
36356ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
36366ce3c06aSMatthew 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);
36376ce3c06aSMatthew G. Knepley         }
36386ce3c06aSMatthew G. Knepley #endif
36396ce3c06aSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
36406ce3c06aSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
36416ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
36426ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
36436ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
36446ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
36456ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
36466ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
36476ce3c06aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
36489ddff745SMatthew G. Knepley             er = GetTetSomethingInverse_Static(ornt[c], r);
36496ce3c06aSMatthew G. Knepley             if (er == eint[c]) {
36506ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
36516ce3c06aSMatthew G. Knepley             } else {
36526ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
36536ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
36546ce3c06aSMatthew G. Knepley             }
36556ce3c06aSMatthew G. Knepley           } else {
3656b598a9d5SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3;
36576ce3c06aSMatthew G. Knepley           }
36586ce3c06aSMatthew G. Knepley         }
36596ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
36606ce3c06aSMatthew G. Knepley #if 1
36616ce3c06aSMatthew 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);
36626ce3c06aSMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
36636ce3c06aSMatthew 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);
36646ce3c06aSMatthew G. Knepley         }
36656ce3c06aSMatthew G. Knepley #endif
36666ce3c06aSMatthew G. Knepley       }
36676ce3c06aSMatthew G. Knepley     }
36686ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
36696ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
36706ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
36716ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
36726ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
36736ce3c06aSMatthew G. Knepley 
36746ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
36756ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
36766ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
36776ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
36786ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
36796ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
36806ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
36816ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
36826ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
36836ce3c06aSMatthew G. Knepley #if 1
36846ce3c06aSMatthew 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);
36856ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
36866ce3c06aSMatthew 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);
36876ce3c06aSMatthew G. Knepley       }
36886ce3c06aSMatthew G. Knepley #endif
36896ce3c06aSMatthew G. Knepley       supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
36906ce3c06aSMatthew G. Knepley       supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
36916ce3c06aSMatthew G. Knepley       supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
36926ce3c06aSMatthew G. Knepley       supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
36936ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
36946ce3c06aSMatthew G. Knepley #if 1
36956ce3c06aSMatthew 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);
36966ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
36976ce3c06aSMatthew 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);
36986ce3c06aSMatthew G. Knepley       }
36996ce3c06aSMatthew G. Knepley #endif
37006ce3c06aSMatthew G. Knepley     }
37016ce3c06aSMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
37026ce3c06aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
37036ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
37046ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
37056ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
37066ce3c06aSMatthew G. Knepley 
37076ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
37086ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
37096ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
37106ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
37116ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
37126ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37136ce3c06aSMatthew G. Knepley #if 1
37146ce3c06aSMatthew 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);
37156ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
37166ce3c06aSMatthew 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);
37176ce3c06aSMatthew G. Knepley       }
37186ce3c06aSMatthew G. Knepley #endif
37196ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
37206ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
37216ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
37226ce3c06aSMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
37236ce3c06aSMatthew 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]);
37246ce3c06aSMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2;
37256ce3c06aSMatthew G. Knepley       }
37266ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
37276ce3c06aSMatthew G. Knepley #if 1
37286ce3c06aSMatthew 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);
37296ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
37306ce3c06aSMatthew 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);
37316ce3c06aSMatthew G. Knepley       }
37326ce3c06aSMatthew G. Knepley #endif
37336ce3c06aSMatthew G. Knepley     }
37346ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
37356ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
37366ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
3737623f4348SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
37386ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
37396ce3c06aSMatthew G. Knepley 
37406ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
37416ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
37426ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
37436ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
37446ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
37456ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37466ce3c06aSMatthew G. Knepley #if 1
37476ce3c06aSMatthew 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);
37486ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
37496ce3c06aSMatthew 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);
37506ce3c06aSMatthew G. Knepley       }
37516ce3c06aSMatthew G. Knepley #endif
37526ce3c06aSMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0;
37536ce3c06aSMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1;
37546ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
37556ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
37566ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
3757623f4348SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
37586ce3c06aSMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
37596ce3c06aSMatthew 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]);
3760b598a9d5SMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2;
3761b598a9d5SMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3;
37626ce3c06aSMatthew G. Knepley       }
37636ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
37646ce3c06aSMatthew G. Knepley #if 1
37656ce3c06aSMatthew 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);
37666ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
37676ce3c06aSMatthew 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);
37686ce3c06aSMatthew G. Knepley       }
37696ce3c06aSMatthew G. Knepley #endif
37706ce3c06aSMatthew G. Knepley     }
37716ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
37726ce3c06aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
37736ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
37746ce3c06aSMatthew G. Knepley       const PetscInt *support, *cone;
37756ce3c06aSMatthew G. Knepley       PetscInt        size, s;
37766ce3c06aSMatthew G. Knepley 
37776ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
37786ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
37796ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
37806ce3c06aSMatthew G. Knepley         PetscInt r = 0;
37816ce3c06aSMatthew G. Knepley 
37826ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
37836ce3c06aSMatthew G. Knepley         if (cone[1] == v) r = 1;
37846ce3c06aSMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
37856ce3c06aSMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax);
37866ce3c06aSMatthew G. Knepley       }
37876ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
37886ce3c06aSMatthew G. Knepley #if 1
37896ce3c06aSMatthew 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);
37906ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
37916ce3c06aSMatthew 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);
37926ce3c06aSMatthew G. Knepley       }
37936ce3c06aSMatthew G. Knepley #endif
37946ce3c06aSMatthew G. Knepley     }
37956ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
37966ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
37976ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
37986ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support;
37996ce3c06aSMatthew G. Knepley       PetscInt       *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s;
38006ce3c06aSMatthew G. Knepley 
38016ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
38026ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
38036ce3c06aSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
38046ce3c06aSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
38056ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
38066ce3c06aSMatthew G. Knepley         PetscInt r = 0;
38076ce3c06aSMatthew G. Knepley 
38086ce3c06aSMatthew G. Knepley         if (support[s] < fMax) {
38096ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
38106ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
38116ce3c06aSMatthew G. Knepley           for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
38126ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
38136ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
38146ce3c06aSMatthew G. Knepley           faceSize += 2;
38156ce3c06aSMatthew G. Knepley         } else {
38166ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax);
38176ce3c06aSMatthew G. Knepley           ++faceSize;
38186ce3c06aSMatthew G. Knepley         }
38196ce3c06aSMatthew G. Knepley       }
38206ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
38216ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
38226ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
38236ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
38246ce3c06aSMatthew G. Knepley 
38256ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
38266ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
38276ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
38286ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
38296ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
38306ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
38316ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
38326ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
38336ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
38346ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
38356ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
38366ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);}
38376ce3c06aSMatthew G. Knepley         }
38386ce3c06aSMatthew G. Knepley       }
38396ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
38406ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
38416ce3c06aSMatthew G. Knepley #if 1
38426ce3c06aSMatthew 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);
38436ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+faceSize+cellSize; ++p) {
38446ce3c06aSMatthew 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);
38456ce3c06aSMatthew G. Knepley       }
38466ce3c06aSMatthew G. Knepley #endif
38476ce3c06aSMatthew G. Knepley     }
38486ce3c06aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
38496ce3c06aSMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
38506ce3c06aSMatthew G. Knepley     break;
38519b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
38522eabf88fSMatthew G. Knepley     /*
38532eabf88fSMatthew G. Knepley      Bottom (viewed from top)    Top
38542eabf88fSMatthew G. Knepley      1---------2---------2       7---------2---------6
38552eabf88fSMatthew G. Knepley      |         |         |       |         |         |
38562eabf88fSMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
38572eabf88fSMatthew G. Knepley      |         |         |       |         |         |
38582eabf88fSMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
38592eabf88fSMatthew G. Knepley      |         |         |       |         |         |
38602eabf88fSMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
38612eabf88fSMatthew G. Knepley      |         |         |       |         |         |
38622eabf88fSMatthew G. Knepley      0---------0---------3       4---------0---------5
38632eabf88fSMatthew G. Knepley      */
38642eabf88fSMatthew G. Knepley     /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
38652eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
38662eabf88fSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
38672eabf88fSMatthew G. Knepley       const PetscInt *cone, *ornt;
38682eabf88fSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
38692eabf88fSMatthew G. Knepley 
38702eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
38712eabf88fSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
38722eabf88fSMatthew G. Knepley       /* A hex */
3873e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
38742eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
38752eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
38762eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3877e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
38782eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
38792eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
38802eabf88fSMatthew G. Knepley       orntNew[3] = 0;
38812eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
38822eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3883e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
38842eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
38852eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
38862eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
38872eabf88fSMatthew G. Knepley #if 1
38882eabf88fSMatthew 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);
38892eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
38902eabf88fSMatthew 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);
38912eabf88fSMatthew G. Knepley       }
38922eabf88fSMatthew G. Knepley #endif
38932eabf88fSMatthew G. Knepley       /* B hex */
3894e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
38952eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
38962eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
38972eabf88fSMatthew G. Knepley       orntNew[1] = 0;
38982eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
3899a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3900e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
39012eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
39022eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
39032eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3904e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
39052eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
39062eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
39072eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
39082eabf88fSMatthew G. Knepley #if 1
39092eabf88fSMatthew 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);
39102eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
39112eabf88fSMatthew 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);
39122eabf88fSMatthew G. Knepley       }
39132eabf88fSMatthew G. Knepley #endif
39142eabf88fSMatthew G. Knepley       /* C hex */
3915e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
39162eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
39172eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
39182eabf88fSMatthew G. Knepley       orntNew[1] = 0;
39192eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
3920a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3921e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
39222eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
3923e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
39242eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
39252eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
3926a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
39272eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
39282eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
39292eabf88fSMatthew G. Knepley #if 1
39302eabf88fSMatthew 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);
39312eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
39322eabf88fSMatthew 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);
39332eabf88fSMatthew G. Knepley       }
39342eabf88fSMatthew G. Knepley #endif
39352eabf88fSMatthew G. Knepley       /* D hex */
3936e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
39372eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
39382eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
39392eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3940e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
39412eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
39422eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
3943a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3944e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
39452eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
39462eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
3947a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
39482eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
39492eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
39502eabf88fSMatthew G. Knepley #if 1
39512eabf88fSMatthew 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);
39522eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
39532eabf88fSMatthew 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);
39542eabf88fSMatthew G. Knepley       }
39552eabf88fSMatthew G. Knepley #endif
39562eabf88fSMatthew G. Knepley       /* E hex */
39572eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
3958a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3959e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
39602eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3961e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
39622eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
39632eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
39642eabf88fSMatthew G. Knepley       orntNew[3] = 0;
39652eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
3966a3cddbf8SMatthew G. Knepley       orntNew[4] = -1;
3967e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
39682eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
3969b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
3970b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
39712eabf88fSMatthew G. Knepley #if 1
3972b164cbf2SMatthew 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);
39732eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
39742eabf88fSMatthew 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);
39752eabf88fSMatthew G. Knepley       }
39762eabf88fSMatthew G. Knepley #endif
39772eabf88fSMatthew G. Knepley       /* F hex */
39782eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
3979a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3980e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
39812eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3982e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
39832eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
39842eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
3985a3cddbf8SMatthew G. Knepley       orntNew[3] = -1;
3986e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
39872eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
39882eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
3989a3cddbf8SMatthew G. Knepley       orntNew[5] = 1;
3990b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
3991b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
39922eabf88fSMatthew G. Knepley #if 1
3993b164cbf2SMatthew 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);
39942eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
39952eabf88fSMatthew 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);
39962eabf88fSMatthew G. Knepley       }
39972eabf88fSMatthew G. Knepley #endif
39982eabf88fSMatthew G. Knepley       /* G hex */
39992eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
4000a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
4001e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
40022eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
40032eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
4004a3cddbf8SMatthew G. Knepley       orntNew[2] = 0;
4005e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
40062eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
4007e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
40082eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
40092eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
4010a3cddbf8SMatthew G. Knepley       orntNew[5] = -3;
4011b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
4012b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
40132eabf88fSMatthew G. Knepley #if 1
4014b164cbf2SMatthew 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);
40152eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
40162eabf88fSMatthew 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);
40172eabf88fSMatthew G. Knepley       }
40182eabf88fSMatthew G. Knepley #endif
40192eabf88fSMatthew G. Knepley       /* H hex */
40202eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
4021a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
4022e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
40232eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
40242eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
4025a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
4026e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
40272eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
40282eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
4029a3cddbf8SMatthew G. Knepley       orntNew[4] = 3;
4030e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
40312eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
4032b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
4033b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
40342eabf88fSMatthew G. Knepley #if 1
4035b164cbf2SMatthew 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);
40362eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
40372eabf88fSMatthew 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);
40382eabf88fSMatthew G. Knepley       }
40392eabf88fSMatthew G. Knepley #endif
40402eabf88fSMatthew G. Knepley     }
40412eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
40422eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
4043854ce69bSBarry Smith     ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
40442eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
40452eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
4046aaebbb9dSMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
40472eabf88fSMatthew 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};
40482eabf88fSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
40492eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
4050aaebbb9dSMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
40512eabf88fSMatthew G. Knepley 
40522eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
4053aaebbb9dSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
4054a3cddbf8SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
4055a3cddbf8SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
4056a3cddbf8SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
4057a3cddbf8SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
4058a3cddbf8SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
4059a3cddbf8SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
4060a3cddbf8SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4;
4061a3cddbf8SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
40622eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4063aaebbb9dSMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
40642eabf88fSMatthew G. Knepley #if 1
40652eabf88fSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
40662eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
40672eabf88fSMatthew 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);
40682eabf88fSMatthew G. Knepley         }
40692eabf88fSMatthew G. Knepley #endif
40702eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
40712eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
40722eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
40732eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
40742eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
40752eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
40762eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
40772eabf88fSMatthew G. Knepley             if (cone[c] == f) break;
40782eabf88fSMatthew G. Knepley           }
4079a3cddbf8SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)];
40802eabf88fSMatthew G. Knepley         }
40812eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
40822eabf88fSMatthew G. Knepley #if 1
40832eabf88fSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
40842eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
40852eabf88fSMatthew 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);
40862eabf88fSMatthew G. Knepley         }
40872eabf88fSMatthew G. Knepley #endif
40882eabf88fSMatthew G. Knepley       }
40892eabf88fSMatthew G. Knepley     }
40902eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
40912eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
40922eabf88fSMatthew 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};
4093afb2665bSMatthew G. Knepley       const PetscInt *cone, *ornt;
4094afb2665bSMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
40952eabf88fSMatthew G. Knepley 
40962eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
4097afb2665bSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
4098afb2665bSMatthew G. Knepley       /* A-D face */
4099afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0;
4100a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
4101a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
4102a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
4103afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4104a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
4105a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
4106a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
4107afb2665bSMatthew G. Knepley       orntNew[3] = -2;
41082eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4109afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
41102eabf88fSMatthew G. Knepley #if 1
41112eabf88fSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
41122eabf88fSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
41132eabf88fSMatthew 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);
41142eabf88fSMatthew G. Knepley       }
41152eabf88fSMatthew G. Knepley #endif
4116afb2665bSMatthew G. Knepley       /* C-D face */
4117afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1;
4118a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
4119a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
4120a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
4121afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4122a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
4123a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
4124a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
4125afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4126afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4127afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4128afb2665bSMatthew G. Knepley #if 1
4129afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4130afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4131afb2665bSMatthew 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);
4132afb2665bSMatthew G. Knepley       }
4133afb2665bSMatthew G. Knepley #endif
4134afb2665bSMatthew G. Knepley       /* B-C face */
4135afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2;
4136afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
4137afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4138afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
4139afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4140afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
4141afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4142afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
4143afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4144afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4145afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4146afb2665bSMatthew G. Knepley #if 1
4147afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4148afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4149afb2665bSMatthew 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);
4150afb2665bSMatthew G. Knepley       }
4151afb2665bSMatthew G. Knepley #endif
4152afb2665bSMatthew G. Knepley       /* A-B face */
4153afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3;
4154afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
4155afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4156afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
4157afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4158afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
4159afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4160afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
4161afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4162afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4163afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4164afb2665bSMatthew G. Knepley #if 1
4165afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4166afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4167afb2665bSMatthew 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);
4168afb2665bSMatthew G. Knepley       }
4169afb2665bSMatthew G. Knepley #endif
4170afb2665bSMatthew G. Knepley       /* E-F face */
4171afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4;
4172a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
4173afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4174a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
4175a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4176a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
4177afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4178a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
4179a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4180afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4181afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4182afb2665bSMatthew G. Knepley #if 1
4183afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4184afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4185afb2665bSMatthew 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);
4186afb2665bSMatthew G. Knepley       }
4187afb2665bSMatthew G. Knepley #endif
4188afb2665bSMatthew G. Knepley       /* F-G face */
4189afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5;
4190a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
4191afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4192a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
4193a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4194a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
4195afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4196a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
4197a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4198afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4199afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4200afb2665bSMatthew G. Knepley #if 1
4201afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4202afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4203afb2665bSMatthew 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);
4204afb2665bSMatthew G. Knepley       }
4205afb2665bSMatthew G. Knepley #endif
4206afb2665bSMatthew G. Knepley       /* G-H face */
4207afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6;
4208afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
4209afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4210afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
4211afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4212afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
4213afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4214afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
4215afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4216afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4217afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4218afb2665bSMatthew G. Knepley #if 1
4219afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4220afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4221afb2665bSMatthew 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);
4222afb2665bSMatthew G. Knepley       }
4223afb2665bSMatthew G. Knepley #endif
4224afb2665bSMatthew G. Knepley       /* E-H face */
4225afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7;
4226a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
4227afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4228a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
4229a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4230a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
4231afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4232a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
4233a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4234afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4235afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4236afb2665bSMatthew G. Knepley #if 1
4237afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4238afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4239afb2665bSMatthew 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);
4240afb2665bSMatthew G. Knepley       }
4241afb2665bSMatthew G. Knepley #endif
4242afb2665bSMatthew G. Knepley       /* A-E face */
4243afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8;
4244a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
4245a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
4246a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
4247afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4248a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
4249a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
4250a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
4251afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4252afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4253afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4254afb2665bSMatthew G. Knepley #if 1
4255afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4256afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4257afb2665bSMatthew 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);
4258afb2665bSMatthew G. Knepley       }
4259afb2665bSMatthew G. Knepley #endif
4260afb2665bSMatthew G. Knepley       /* D-F face */
4261afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9;
4262afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
4263afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4264afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
4265afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4266afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
4267afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4268afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
4269afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4270afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4271afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4272afb2665bSMatthew G. Knepley #if 1
4273afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4274afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4275afb2665bSMatthew 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);
4276afb2665bSMatthew G. Knepley       }
4277afb2665bSMatthew G. Knepley #endif
4278afb2665bSMatthew G. Knepley       /* C-G face */
4279afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10;
4280a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
4281afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4282a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
4283a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4284a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
4285afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4286a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
4287a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4288afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4289afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4290afb2665bSMatthew G. Knepley #if 1
4291afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4292afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4293afb2665bSMatthew 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);
4294afb2665bSMatthew G. Knepley       }
4295afb2665bSMatthew G. Knepley #endif
4296afb2665bSMatthew G. Knepley       /* B-H face */
4297afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11;
4298a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
4299a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
4300a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
4301a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4302a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
4303a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
4304a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
4305a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4306afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4307afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4308afb2665bSMatthew G. Knepley #if 1
4309afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4310afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4311afb2665bSMatthew 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);
4312afb2665bSMatthew G. Knepley       }
4313afb2665bSMatthew G. Knepley #endif
4314afb2665bSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
4315afb2665bSMatthew G. Knepley         newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
43162eabf88fSMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
43172eabf88fSMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
43182eabf88fSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
43192eabf88fSMatthew G. Knepley #if 1
43202eabf88fSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
43212eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
43222eabf88fSMatthew 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);
43232eabf88fSMatthew G. Knepley         }
43242eabf88fSMatthew G. Knepley #endif
43252eabf88fSMatthew G. Knepley       }
43262eabf88fSMatthew G. Knepley     }
43272eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
43282eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
43292eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
43302eabf88fSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
43312eabf88fSMatthew G. Knepley 
43322eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
43332eabf88fSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
43342eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
43352eabf88fSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
43362eabf88fSMatthew G. Knepley 
43372eabf88fSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
43382eabf88fSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
43392eabf88fSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
43402eabf88fSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
43412eabf88fSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
43422eabf88fSMatthew G. Knepley #if 1
43432eabf88fSMatthew 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);
43442eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
43452eabf88fSMatthew 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);
43462eabf88fSMatthew G. Knepley         }
43472eabf88fSMatthew G. Knepley #endif
43482eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
43492eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
43502eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
43512eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
43522eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
43532eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
43542eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
43552eabf88fSMatthew G. Knepley             if (cone[c] == e) break;
43562eabf88fSMatthew G. Knepley           }
43572eabf88fSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
43582eabf88fSMatthew G. Knepley         }
43592eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
43602eabf88fSMatthew G. Knepley #if 1
43612eabf88fSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
43622eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
43632eabf88fSMatthew 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);
43642eabf88fSMatthew G. Knepley         }
43652eabf88fSMatthew G. Knepley #endif
43662eabf88fSMatthew G. Knepley       }
43672eabf88fSMatthew G. Knepley     }
43682eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
43692eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
43706b852384SMatthew 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};
43712eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
43726b852384SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
43732eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
43742eabf88fSMatthew G. Knepley 
43752eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
43762eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
43772eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
43782eabf88fSMatthew G. Knepley 
43792eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
43802eabf88fSMatthew G. Knepley         coneNew[1] = newv;
43812eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
43822eabf88fSMatthew G. Knepley #if 1
43832eabf88fSMatthew 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);
43842eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
43852eabf88fSMatthew 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);
43862eabf88fSMatthew G. Knepley         }
43872eabf88fSMatthew G. Knepley #endif
43882eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
43892eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
43902eabf88fSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
43912eabf88fSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
43922eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
43936b852384SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
43946b852384SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
43956b852384SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
43962eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
4397a3cddbf8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
43982eabf88fSMatthew G. Knepley         }
43992eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
44002eabf88fSMatthew G. Knepley #if 1
44012eabf88fSMatthew 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);
44022eabf88fSMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
44032eabf88fSMatthew 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);
44042eabf88fSMatthew G. Knepley         }
44052eabf88fSMatthew G. Knepley #endif
44062eabf88fSMatthew G. Knepley       }
44072eabf88fSMatthew G. Knepley     }
44082eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
44092eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
44102eabf88fSMatthew 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};
44112eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
44122eabf88fSMatthew G. Knepley       const PetscInt *cone;
44132eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
44142eabf88fSMatthew G. Knepley 
44152eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
44162eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
44172eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
44182eabf88fSMatthew G. Knepley 
44192eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
44202eabf88fSMatthew G. Knepley         coneNew[1] = newv;
44212eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
44222eabf88fSMatthew G. Knepley #if 1
44232eabf88fSMatthew 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);
44242eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
44252eabf88fSMatthew 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);
44262eabf88fSMatthew G. Knepley         }
44272eabf88fSMatthew G. Knepley #endif
44282eabf88fSMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
44292eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
44302eabf88fSMatthew G. Knepley #if 1
44312eabf88fSMatthew 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);
44322eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
44332eabf88fSMatthew 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);
44342eabf88fSMatthew G. Knepley         }
44352eabf88fSMatthew G. Knepley #endif
44362eabf88fSMatthew G. Knepley       }
44372eabf88fSMatthew G. Knepley     }
44382eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
44392eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
44402eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
44412eabf88fSMatthew G. Knepley       const PetscInt *support, *cone;
44422eabf88fSMatthew G. Knepley       PetscInt        size, s;
44432eabf88fSMatthew G. Knepley 
44442eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
44452eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
44462eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
44472eabf88fSMatthew G. Knepley         PetscInt r = 0;
44482eabf88fSMatthew G. Knepley 
44492eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
44502eabf88fSMatthew G. Knepley         if (cone[1] == v) r = 1;
44512eabf88fSMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
44522eabf88fSMatthew G. Knepley       }
44532eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
44542eabf88fSMatthew G. Knepley #if 1
44552eabf88fSMatthew 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);
44562eabf88fSMatthew G. Knepley       for (p = 0; p < size; ++p) {
44572eabf88fSMatthew 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);
44582eabf88fSMatthew G. Knepley       }
44592eabf88fSMatthew G. Knepley #endif
44602eabf88fSMatthew G. Knepley     }
44612eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
44622eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
44632eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
44642eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
44652eabf88fSMatthew G. Knepley       PetscInt        size, s;
44662eabf88fSMatthew G. Knepley 
44672eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
44682eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
44692eabf88fSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
44702eabf88fSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
44712eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
44722eabf88fSMatthew G. Knepley         PetscInt r;
44732eabf88fSMatthew G. Knepley 
44742eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4475a660e16cSMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
44762eabf88fSMatthew G. Knepley         supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r;
44772eabf88fSMatthew G. Knepley       }
44782eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
44792eabf88fSMatthew G. Knepley #if 1
44802eabf88fSMatthew 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);
44812eabf88fSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
44822eabf88fSMatthew 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);
44832eabf88fSMatthew G. Knepley       }
44842eabf88fSMatthew G. Knepley #endif
44852eabf88fSMatthew G. Knepley     }
44862eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
44872eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
44882eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
44892eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
44902eabf88fSMatthew G. Knepley       PetscInt        size, s;
44912eabf88fSMatthew G. Knepley 
44922eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
44932eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
44940793999aSMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 +  (f - fStart)*4 + r;
44952eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
44962eabf88fSMatthew G. Knepley         PetscInt r;
44972eabf88fSMatthew G. Knepley 
44982eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
44992eabf88fSMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
45002eabf88fSMatthew G. Knepley         supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r;
45012eabf88fSMatthew G. Knepley       }
45022eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
45032eabf88fSMatthew G. Knepley #if 1
45042eabf88fSMatthew 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);
45052eabf88fSMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
45062eabf88fSMatthew 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);
45072eabf88fSMatthew G. Knepley       }
45082eabf88fSMatthew G. Knepley #endif
45092eabf88fSMatthew G. Knepley     }
45102eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
45112eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
45122eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
45132eabf88fSMatthew G. Knepley       PetscInt       supportNew[6];
45142eabf88fSMatthew G. Knepley 
45152eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
45162eabf88fSMatthew G. Knepley         supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
45172eabf88fSMatthew G. Knepley       }
45182eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
45192eabf88fSMatthew G. Knepley     }
4520da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
45212eabf88fSMatthew G. Knepley     break;
45229b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
452327fcede3SMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
452427fcede3SMatthew G. Knepley     /*
452527fcede3SMatthew G. Knepley      Bottom (viewed from top)    Top
452627fcede3SMatthew G. Knepley      1---------2---------2       7---------2---------6
452727fcede3SMatthew G. Knepley      |         |         |       |         |         |
452827fcede3SMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
452927fcede3SMatthew G. Knepley      |         |         |       |         |         |
453027fcede3SMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
453127fcede3SMatthew G. Knepley      |         |         |       |         |         |
453227fcede3SMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
453327fcede3SMatthew G. Knepley      |         |         |       |         |         |
453427fcede3SMatthew G. Knepley      0---------0---------3       4---------0---------5
453527fcede3SMatthew G. Knepley      */
453627fcede3SMatthew G. Knepley     /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
453727fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
453827fcede3SMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
453927fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
454027fcede3SMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
454127fcede3SMatthew G. Knepley 
454227fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
454327fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
454427fcede3SMatthew G. Knepley       /* A hex */
454527fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
454627fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
454727fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
454827fcede3SMatthew G. Knepley       orntNew[1] = 0;
454927fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
455027fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
455127fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
455227fcede3SMatthew G. Knepley       orntNew[3] = 0;
455327fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
455427fcede3SMatthew G. Knepley       orntNew[4] = 0;
455527fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
455627fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
455727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
455827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
455927fcede3SMatthew G. Knepley #if 1
456027fcede3SMatthew 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);
456127fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
456227fcede3SMatthew 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);
456327fcede3SMatthew G. Knepley       }
456427fcede3SMatthew G. Knepley #endif
456527fcede3SMatthew G. Knepley       /* B hex */
456627fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
456727fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
456827fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
456927fcede3SMatthew G. Knepley       orntNew[1] = 0;
457027fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
457127fcede3SMatthew G. Knepley       orntNew[2] = -1;
457227fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
457327fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
457427fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
457527fcede3SMatthew G. Knepley       orntNew[4] = 0;
457627fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
457727fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
457827fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
457927fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
458027fcede3SMatthew G. Knepley #if 1
458127fcede3SMatthew 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);
458227fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
458327fcede3SMatthew 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);
458427fcede3SMatthew G. Knepley       }
458527fcede3SMatthew G. Knepley #endif
458627fcede3SMatthew G. Knepley       /* C hex */
458727fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
458827fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
458927fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
459027fcede3SMatthew G. Knepley       orntNew[1] = 0;
459127fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
459227fcede3SMatthew G. Knepley       orntNew[2] = -1;
459327fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
459427fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
459527fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
459627fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
459727fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
459827fcede3SMatthew G. Knepley       orntNew[5] = -4;
459927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
460027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
460127fcede3SMatthew G. Knepley #if 1
460227fcede3SMatthew 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);
460327fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
460427fcede3SMatthew 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);
460527fcede3SMatthew G. Knepley       }
460627fcede3SMatthew G. Knepley #endif
460727fcede3SMatthew G. Knepley       /* D hex */
460827fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
460927fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
461027fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
461127fcede3SMatthew G. Knepley       orntNew[1] = 0;
461227fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
461327fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
461427fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
461527fcede3SMatthew G. Knepley       orntNew[3] = 0;
461627fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
461727fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
461827fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
461927fcede3SMatthew G. Knepley       orntNew[5] = -4;
462027fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
462127fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
462227fcede3SMatthew G. Knepley #if 1
462327fcede3SMatthew 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);
462427fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
462527fcede3SMatthew 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);
462627fcede3SMatthew G. Knepley       }
462727fcede3SMatthew G. Knepley #endif
462827fcede3SMatthew G. Knepley       /* E hex */
462927fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
463027fcede3SMatthew G. Knepley       orntNew[0] = -4;
463127fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
463227fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
463327fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
463427fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
463527fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
463627fcede3SMatthew G. Knepley       orntNew[3] = 0;
463727fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
463827fcede3SMatthew G. Knepley       orntNew[4] = -1;
463927fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
464027fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
464127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
464227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
464327fcede3SMatthew G. Knepley #if 1
464427fcede3SMatthew 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);
464527fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
464627fcede3SMatthew 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);
464727fcede3SMatthew G. Knepley       }
464827fcede3SMatthew G. Knepley #endif
464927fcede3SMatthew G. Knepley       /* F hex */
465027fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
465127fcede3SMatthew G. Knepley       orntNew[0] = -4;
465227fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
465327fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
465427fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
465527fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
465627fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
465727fcede3SMatthew G. Knepley       orntNew[3] = -1;
465827fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
465927fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
466027fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
466127fcede3SMatthew G. Knepley       orntNew[5] = 1;
466227fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
466327fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
466427fcede3SMatthew G. Knepley #if 1
466527fcede3SMatthew 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);
466627fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
466727fcede3SMatthew 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);
466827fcede3SMatthew G. Knepley       }
466927fcede3SMatthew G. Knepley #endif
467027fcede3SMatthew G. Knepley       /* G hex */
467127fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
467227fcede3SMatthew G. Knepley       orntNew[0] = -4;
467327fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
467427fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
467527fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
467627fcede3SMatthew G. Knepley       orntNew[2] = 0;
467727fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
467827fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
467927fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
468027fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
468127fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
468227fcede3SMatthew G. Knepley       orntNew[5] = -3;
468327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
468427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
468527fcede3SMatthew G. Knepley #if 1
468627fcede3SMatthew 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);
468727fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
468827fcede3SMatthew 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);
468927fcede3SMatthew G. Knepley       }
469027fcede3SMatthew G. Knepley #endif
469127fcede3SMatthew G. Knepley       /* H hex */
469227fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
469327fcede3SMatthew G. Knepley       orntNew[0] = -4;
469427fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
469527fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
469627fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
469727fcede3SMatthew G. Knepley       orntNew[2] = -1;
469827fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
469927fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
470027fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
470127fcede3SMatthew G. Knepley       orntNew[4] = 3;
470227fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
470327fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
470427fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
470527fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
470627fcede3SMatthew G. Knepley #if 1
470727fcede3SMatthew 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);
470827fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
470927fcede3SMatthew 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);
471027fcede3SMatthew G. Knepley       }
471127fcede3SMatthew G. Knepley #endif
471227fcede3SMatthew G. Knepley     }
471327fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces: Front, Back, Sides */
471427fcede3SMatthew G. Knepley     /*
471527fcede3SMatthew G. Knepley      3---------2---------2
471627fcede3SMatthew G. Knepley      |         |         |
471727fcede3SMatthew G. Knepley      |    D    2    C    |
471827fcede3SMatthew G. Knepley      |         |         |
471927fcede3SMatthew G. Knepley      3----3----0----1----1
472027fcede3SMatthew G. Knepley      |         |         |
472127fcede3SMatthew G. Knepley      |    A    0    B    |
472227fcede3SMatthew G. Knepley      |         |         |
472327fcede3SMatthew G. Knepley      0---------0---------1
472427fcede3SMatthew G. Knepley      */
472527fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
472627fcede3SMatthew G. Knepley       const PetscInt  newp = (cMax - cStart)*8 + (c - cMax)*4;
472727fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
4728d273725eSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6], o, of, i;
472927fcede3SMatthew G. Knepley 
473027fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
473127fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
473227fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
4733d273725eSMatthew G. Knepley       o = ornt[0] < 0 ? -1 : 1;
473427fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
473527fcede3SMatthew G. Knepley         PetscInt subfA = GetQuadSubface_Static(ornt[0], r);
473627fcede3SMatthew G. Knepley         PetscInt edgeA = GetQuadEdge_Static(ornt[0], r);
4737d273725eSMatthew G. Knepley         PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4);
473827fcede3SMatthew 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]);
473927fcede3SMatthew G. Knepley         coneNew[0]         = fStartNew + (cone[0] - fStart)*4 + subfA;
474027fcede3SMatthew G. Knepley         orntNew[0]         = ornt[0];
474127fcede3SMatthew G. Knepley         coneNew[1]         = fStartNew + (cone[1] - fStart)*4 + subfA;
474227fcede3SMatthew G. Knepley         orntNew[1]         = ornt[0];
4743d273725eSMatthew G. Knepley         of = fornt[edgeA] < 0 ? -1 : 1;
4744d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], r) + 2;
4745d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0);
4746d273725eSMatthew G. Knepley         orntNew[i] = ornt[edgeA];
4747d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2;
4748d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeA;
4749d273725eSMatthew G. Knepley         orntNew[i] = 0;
4750d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2;
4751d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeB;
4752d273725eSMatthew G. Knepley         orntNew[i] = -2;
4753d273725eSMatthew G. Knepley         of = fornt[edgeB] < 0 ? -1 : 1;
4754d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2;
4755d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1);
4756d273725eSMatthew G. Knepley         orntNew[i] = ornt[edgeB];
475727fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
475827fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
475927fcede3SMatthew G. Knepley #if 1
476027fcede3SMatthew 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);
476127fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
476227fcede3SMatthew 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);
476327fcede3SMatthew G. Knepley         }
476427fcede3SMatthew G. Knepley         for (p = 2; p < 6; ++p) {
476527fcede3SMatthew 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);
476627fcede3SMatthew G. Knepley         }
476727fcede3SMatthew G. Knepley #endif
476827fcede3SMatthew G. Knepley       }
476927fcede3SMatthew G. Knepley     }
477027fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
477127fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
4772854ce69bSBarry Smith     ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
477327fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
477427fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
477527fcede3SMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
477627fcede3SMatthew 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};
477727fcede3SMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
477827fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
477927fcede3SMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
478027fcede3SMatthew G. Knepley 
478127fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
478227fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
478327fcede3SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
478427fcede3SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
478527fcede3SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
478627fcede3SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
478727fcede3SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
478827fcede3SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
478927fcede3SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4;
479027fcede3SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
479127fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
479227fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
479327fcede3SMatthew G. Knepley #if 1
479427fcede3SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
479527fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
479627fcede3SMatthew G. Knepley           if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
479727fcede3SMatthew G. Knepley         }
479827fcede3SMatthew G. Knepley #endif
479927fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
480027fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
480127fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
480227fcede3SMatthew G. Knepley           PetscInt subf;
480327fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
480427fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
480527fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
480627fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
480727fcede3SMatthew G. Knepley             if (cone[c] == f) break;
480827fcede3SMatthew G. Knepley           }
480927fcede3SMatthew G. Knepley           subf = GetQuadSubfaceInverse_Static(ornt[c], r);
481027fcede3SMatthew G. Knepley           if (support[s] < cMax) {
481127fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf];
481227fcede3SMatthew G. Knepley           } else {
481327fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax       - cStart)*8 + (support[s] - cMax)*4 + subf;
481427fcede3SMatthew G. Knepley           }
481527fcede3SMatthew G. Knepley         }
481627fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
481727fcede3SMatthew G. Knepley #if 1
481827fcede3SMatthew 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);
481927fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
482027fcede3SMatthew 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);
482127fcede3SMatthew G. Knepley         }
482227fcede3SMatthew G. Knepley #endif
482327fcede3SMatthew G. Knepley       }
482427fcede3SMatthew G. Knepley     }
4825d273725eSMatthew G. Knepley     /* Interior cell faces have 4 edges and 2 cells */
482627fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
482727fcede3SMatthew 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};
482827fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
482927fcede3SMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
483027fcede3SMatthew G. Knepley 
483127fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
483227fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
483327fcede3SMatthew G. Knepley       /* A-D face */
483427fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0;
483527fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
483627fcede3SMatthew G. Knepley       orntNew[0] = 0;
483727fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
483827fcede3SMatthew G. Knepley       orntNew[1] = 0;
483927fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
484027fcede3SMatthew G. Knepley       orntNew[2] = -2;
484127fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
484227fcede3SMatthew G. Knepley       orntNew[3] = -2;
484327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
484427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
484527fcede3SMatthew G. Knepley #if 1
484627fcede3SMatthew 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);
484727fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
484827fcede3SMatthew 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);
484927fcede3SMatthew G. Knepley       }
485027fcede3SMatthew G. Knepley #endif
485127fcede3SMatthew G. Knepley       /* C-D face */
485227fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1;
485327fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
485427fcede3SMatthew G. Knepley       orntNew[0] = 0;
485527fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
485627fcede3SMatthew G. Knepley       orntNew[1] = 0;
485727fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
485827fcede3SMatthew G. Knepley       orntNew[2] = -2;
485927fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
486027fcede3SMatthew G. Knepley       orntNew[3] = -2;
486127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
486227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
486327fcede3SMatthew G. Knepley #if 1
486427fcede3SMatthew 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);
486527fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
486627fcede3SMatthew 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);
486727fcede3SMatthew G. Knepley       }
486827fcede3SMatthew G. Knepley #endif
486927fcede3SMatthew G. Knepley       /* B-C face */
487027fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2;
487127fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
487227fcede3SMatthew G. Knepley       orntNew[0] = -2;
487327fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
487427fcede3SMatthew G. Knepley       orntNew[1] = 0;
487527fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
487627fcede3SMatthew G. Knepley       orntNew[2] = 0;
487727fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
487827fcede3SMatthew G. Knepley       orntNew[3] = -2;
487927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
488027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
488127fcede3SMatthew G. Knepley #if 1
488227fcede3SMatthew 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);
488327fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
488427fcede3SMatthew 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);
488527fcede3SMatthew G. Knepley       }
488627fcede3SMatthew G. Knepley #endif
488727fcede3SMatthew G. Knepley       /* A-B face */
488827fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3;
488927fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
489027fcede3SMatthew G. Knepley       orntNew[0] = -2;
489127fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
489227fcede3SMatthew G. Knepley       orntNew[1] = 0;
489327fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
489427fcede3SMatthew G. Knepley       orntNew[2] = 0;
489527fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
489627fcede3SMatthew G. Knepley       orntNew[3] = -2;
489727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
489827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
489927fcede3SMatthew G. Knepley #if 1
490027fcede3SMatthew 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);
490127fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
490227fcede3SMatthew 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);
490327fcede3SMatthew G. Knepley       }
490427fcede3SMatthew G. Knepley #endif
490527fcede3SMatthew G. Knepley       /* E-F face */
490627fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4;
490727fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
490827fcede3SMatthew G. Knepley       orntNew[0] = -2;
490927fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
491027fcede3SMatthew G. Knepley       orntNew[1] = -2;
491127fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
491227fcede3SMatthew G. Knepley       orntNew[2] = 0;
491327fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
491427fcede3SMatthew G. Knepley       orntNew[3] = 0;
491527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
491627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
491727fcede3SMatthew G. Knepley #if 1
491827fcede3SMatthew 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);
491927fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
492027fcede3SMatthew 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);
492127fcede3SMatthew G. Knepley       }
492227fcede3SMatthew G. Knepley #endif
492327fcede3SMatthew G. Knepley       /* F-G face */
492427fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5;
492527fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
492627fcede3SMatthew G. Knepley       orntNew[0] = -2;
492727fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
492827fcede3SMatthew G. Knepley       orntNew[1] = -2;
492927fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
493027fcede3SMatthew G. Knepley       orntNew[2] = 0;
493127fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
493227fcede3SMatthew G. Knepley       orntNew[3] = 0;
493327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
493427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
493527fcede3SMatthew G. Knepley #if 1
493627fcede3SMatthew 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);
493727fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
493827fcede3SMatthew 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);
493927fcede3SMatthew G. Knepley       }
494027fcede3SMatthew G. Knepley #endif
494127fcede3SMatthew G. Knepley       /* G-H face */
494227fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6;
494327fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
494427fcede3SMatthew G. Knepley       orntNew[0] = -2;
494527fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
494627fcede3SMatthew G. Knepley       orntNew[1] = 0;
494727fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
494827fcede3SMatthew G. Knepley       orntNew[2] = 0;
494927fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
495027fcede3SMatthew G. Knepley       orntNew[3] = -2;
495127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
495227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
495327fcede3SMatthew G. Knepley #if 1
495427fcede3SMatthew 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);
495527fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
495627fcede3SMatthew 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);
495727fcede3SMatthew G. Knepley       }
495827fcede3SMatthew G. Knepley #endif
495927fcede3SMatthew G. Knepley       /* E-H face */
496027fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7;
496127fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
496227fcede3SMatthew G. Knepley       orntNew[0] = -2;
496327fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
496427fcede3SMatthew G. Knepley       orntNew[1] = -2;
496527fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
496627fcede3SMatthew G. Knepley       orntNew[2] = 0;
496727fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
496827fcede3SMatthew G. Knepley       orntNew[3] = 0;
496927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
497027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
497127fcede3SMatthew G. Knepley #if 1
497227fcede3SMatthew 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);
497327fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
497427fcede3SMatthew 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);
497527fcede3SMatthew G. Knepley       }
497627fcede3SMatthew G. Knepley #endif
497727fcede3SMatthew G. Knepley       /* A-E face */
497827fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8;
497927fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
498027fcede3SMatthew G. Knepley       orntNew[0] = 0;
498127fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
498227fcede3SMatthew G. Knepley       orntNew[1] = 0;
498327fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
498427fcede3SMatthew G. Knepley       orntNew[2] = -2;
498527fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
498627fcede3SMatthew G. Knepley       orntNew[3] = -2;
498727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
498827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
498927fcede3SMatthew G. Knepley #if 1
499027fcede3SMatthew 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);
499127fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
499227fcede3SMatthew 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);
499327fcede3SMatthew G. Knepley       }
499427fcede3SMatthew G. Knepley #endif
499527fcede3SMatthew G. Knepley       /* D-F face */
499627fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9;
499727fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
499827fcede3SMatthew G. Knepley       orntNew[0] = -2;
499927fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
500027fcede3SMatthew G. Knepley       orntNew[1] = 0;
500127fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
500227fcede3SMatthew G. Knepley       orntNew[2] = 0;
500327fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
500427fcede3SMatthew G. Knepley       orntNew[3] = -2;
500527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
500627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
500727fcede3SMatthew G. Knepley #if 1
500827fcede3SMatthew 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);
500927fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
501027fcede3SMatthew 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);
501127fcede3SMatthew G. Knepley       }
501227fcede3SMatthew G. Knepley #endif
501327fcede3SMatthew G. Knepley       /* C-G face */
501427fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10;
501527fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
501627fcede3SMatthew G. Knepley       orntNew[0] = -2;
501727fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
501827fcede3SMatthew G. Knepley       orntNew[1] = -2;
501927fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
502027fcede3SMatthew G. Knepley       orntNew[2] = 0;
502127fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
502227fcede3SMatthew G. Knepley       orntNew[3] = 0;
502327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
502427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
502527fcede3SMatthew G. Knepley #if 1
502627fcede3SMatthew 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);
502727fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
502827fcede3SMatthew 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);
502927fcede3SMatthew G. Knepley       }
503027fcede3SMatthew G. Knepley #endif
503127fcede3SMatthew G. Knepley       /* B-H face */
503227fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11;
503327fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
503427fcede3SMatthew G. Knepley       orntNew[0] = 0;
503527fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
503627fcede3SMatthew G. Knepley       orntNew[1] = -2;
503727fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
503827fcede3SMatthew G. Knepley       orntNew[2] = -2;
503927fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
504027fcede3SMatthew G. Knepley       orntNew[3] = 0;
504127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
504227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
504327fcede3SMatthew G. Knepley #if 1
504427fcede3SMatthew 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);
504527fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
504627fcede3SMatthew 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);
504727fcede3SMatthew G. Knepley       }
504827fcede3SMatthew G. Knepley #endif
504927fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
505027fcede3SMatthew G. Knepley         newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
505127fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
505227fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
505327fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
505427fcede3SMatthew G. Knepley #if 1
505527fcede3SMatthew 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);
505627fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
505727fcede3SMatthew 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);
505827fcede3SMatthew G. Knepley         }
505927fcede3SMatthew G. Knepley #endif
506027fcede3SMatthew G. Knepley       }
506127fcede3SMatthew G. Knepley     }
506227fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
506327fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
506427fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
506527fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
506627fcede3SMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
506727fcede3SMatthew G. Knepley 
506827fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
506927fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
507027fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
507127fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
507227fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
507327fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
507427fcede3SMatthew G. Knepley 
507527fcede3SMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
507627fcede3SMatthew G. Knepley         orntNew[0]   = ornt[0];
507727fcede3SMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
507827fcede3SMatthew G. Knepley         orntNew[1]   = ornt[1];
507927fcede3SMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax);
508027fcede3SMatthew G. Knepley         orntNew[2+r] = 0;
508127fcede3SMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd      - eMax) + (f - fMax);
508227fcede3SMatthew G. Knepley         orntNew[3-r] = 0;
508327fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
508427fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
508527fcede3SMatthew G. Knepley #if 1
508627fcede3SMatthew 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);
508727fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
508827fcede3SMatthew 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);
508927fcede3SMatthew G. Knepley         }
509027fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
509127fcede3SMatthew 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);
509227fcede3SMatthew G. Knepley         }
509327fcede3SMatthew G. Knepley #endif
509427fcede3SMatthew G. Knepley         for (s = 0; s < size; ++s) {
509527fcede3SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
5096d273725eSMatthew G. Knepley           PetscInt        o, of;
509727fcede3SMatthew G. Knepley 
509827fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
509927fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
5100d273725eSMatthew G. Knepley           o = orntCell[0] < 0 ? -1 : 1;
510127fcede3SMatthew G. Knepley           for (c = 2; c < 6; ++c) if (coneCell[c] == f) break;
510227fcede3SMatthew 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]);
510327fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
5104d273725eSMatthew G. Knepley           of = fornt[c-2] < 0 ? -1 : 1;
5105d273725eSMatthew 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;
510627fcede3SMatthew G. Knepley         }
510727fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
510827fcede3SMatthew G. Knepley #if 1
510927fcede3SMatthew 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);
511027fcede3SMatthew G. Knepley         for (p = 0; p < size; ++p) {
511127fcede3SMatthew 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);
511227fcede3SMatthew G. Knepley         }
511327fcede3SMatthew G. Knepley #endif
511427fcede3SMatthew G. Knepley       }
511527fcede3SMatthew G. Knepley     }
511627fcede3SMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
511727fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
511827fcede3SMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4;
511927fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
512027fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
512127fcede3SMatthew G. Knepley       PetscInt        supportNew[2];
512227fcede3SMatthew G. Knepley 
512327fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
512427fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
512527fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
5126d273725eSMatthew G. Knepley #if 0
512727fcede3SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r);
512827fcede3SMatthew G. Knepley         orntNew[0] = 0;
512927fcede3SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r);
513027fcede3SMatthew G. Knepley         orntNew[1] = 0;
513127fcede3SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax);
513227fcede3SMatthew G. Knepley         orntNew[2] = 0;
513327fcede3SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd                                   - fMax) + (c - cMax);
513427fcede3SMatthew G. Knepley         orntNew[3] = 0;
5135d273725eSMatthew G. Knepley #else
5136d273725eSMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r;
5137d273725eSMatthew G. Knepley         orntNew[0] = 0;
5138d273725eSMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r;
5139d273725eSMatthew G. Knepley         orntNew[1] = 0;
5140d273725eSMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax);
5141d273725eSMatthew G. Knepley         orntNew[2] = 0;
5142d273725eSMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd      - fMax) + (c - cMax);
5143d273725eSMatthew G. Knepley         orntNew[3] = 0;
5144d273725eSMatthew G. Knepley #endif
514527fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
514627fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
514727fcede3SMatthew G. Knepley #if 1
514827fcede3SMatthew 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);
514927fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
515027fcede3SMatthew 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);
515127fcede3SMatthew G. Knepley         }
515227fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
515327fcede3SMatthew 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);
515427fcede3SMatthew G. Knepley         }
515527fcede3SMatthew G. Knepley #endif
515627fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r);
515727fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4);
515827fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
515927fcede3SMatthew G. Knepley #if 1
516027fcede3SMatthew 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);
516127fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
516227fcede3SMatthew 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);
516327fcede3SMatthew G. Knepley         }
516427fcede3SMatthew G. Knepley #endif
516527fcede3SMatthew G. Knepley       }
516627fcede3SMatthew G. Knepley     }
516727fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
516827fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
516927fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
517027fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
517127fcede3SMatthew G. Knepley 
517227fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
517327fcede3SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
517427fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
517527fcede3SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
517627fcede3SMatthew G. Knepley 
517727fcede3SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
517827fcede3SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
517927fcede3SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
518027fcede3SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
518127fcede3SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
518227fcede3SMatthew G. Knepley #if 1
518327fcede3SMatthew 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);
518427fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
518527fcede3SMatthew 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);
518627fcede3SMatthew G. Knepley         }
518727fcede3SMatthew G. Knepley #endif
518827fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
518927fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
519027fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
519127fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
519227fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
519327fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
519427fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
519527fcede3SMatthew G. Knepley             if (cone[c] == e) break;
519627fcede3SMatthew G. Knepley           }
519727fcede3SMatthew G. Knepley           if (support[s] < fMax) {
519827fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4;
519927fcede3SMatthew G. Knepley           } else {
520027fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
520127fcede3SMatthew G. Knepley           }
520227fcede3SMatthew G. Knepley         }
520327fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
520427fcede3SMatthew G. Knepley #if 1
520527fcede3SMatthew 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);
520627fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
520727fcede3SMatthew 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);
520827fcede3SMatthew G. Knepley         }
520927fcede3SMatthew G. Knepley #endif
521027fcede3SMatthew G. Knepley       }
521127fcede3SMatthew G. Knepley     }
521227fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
521327fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
521427fcede3SMatthew 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};
521527fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
521627fcede3SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
521727fcede3SMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
521827fcede3SMatthew G. Knepley 
521927fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
522027fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
522127fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
522227fcede3SMatthew G. Knepley 
522327fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
522427fcede3SMatthew G. Knepley         coneNew[1] = newv;
522527fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
522627fcede3SMatthew G. Knepley #if 1
522727fcede3SMatthew 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);
522827fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
522927fcede3SMatthew 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);
523027fcede3SMatthew G. Knepley         }
523127fcede3SMatthew G. Knepley #endif
523227fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
523327fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
523427fcede3SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
523527fcede3SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
523627fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
523727fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
523827fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
523927fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
524027fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
524127fcede3SMatthew G. Knepley           if (support[s] < cMax) {
524227fcede3SMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
524327fcede3SMatthew G. Knepley           } else {
5244d273725eSMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r;
524527fcede3SMatthew G. Knepley           }
524627fcede3SMatthew G. Knepley         }
524727fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
524827fcede3SMatthew G. Knepley #if 1
524927fcede3SMatthew 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);
525027fcede3SMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
525127fcede3SMatthew 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);
525227fcede3SMatthew G. Knepley         }
525327fcede3SMatthew G. Knepley #endif
525427fcede3SMatthew G. Knepley       }
525527fcede3SMatthew G. Knepley     }
525627fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
525727fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
525827fcede3SMatthew 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};
525927fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
526027fcede3SMatthew G. Knepley       const PetscInt *cone;
526127fcede3SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
526227fcede3SMatthew G. Knepley 
526327fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
526427fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
526527fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
526627fcede3SMatthew G. Knepley 
526727fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart);
526827fcede3SMatthew G. Knepley         coneNew[1] = newv;
526927fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
527027fcede3SMatthew G. Knepley #if 1
527127fcede3SMatthew 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);
527227fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
527327fcede3SMatthew 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);
527427fcede3SMatthew G. Knepley         }
527527fcede3SMatthew G. Knepley #endif
527627fcede3SMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
527727fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
527827fcede3SMatthew G. Knepley #if 1
527927fcede3SMatthew 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);
528027fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
528127fcede3SMatthew 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);
528227fcede3SMatthew G. Knepley         }
528327fcede3SMatthew G. Knepley #endif
528427fcede3SMatthew G. Knepley       }
528527fcede3SMatthew G. Knepley     }
528627fcede3SMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
528727fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
528827fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
528927fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
529027fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
529127fcede3SMatthew G. Knepley 
529227fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
529327fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
529427fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
529527fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
529627fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
529727fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
529827fcede3SMatthew G. Knepley #if 1
529927fcede3SMatthew G. Knepley       if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
530027fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
530127fcede3SMatthew G. Knepley         if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
530227fcede3SMatthew G. Knepley       }
530327fcede3SMatthew G. Knepley #endif
530427fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
530527fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
530627fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
530727fcede3SMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
530827fcede3SMatthew 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]);
530927fcede3SMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2;
531027fcede3SMatthew G. Knepley       }
531127fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
531227fcede3SMatthew G. Knepley #if 1
531327fcede3SMatthew 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);
531427fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
531527fcede3SMatthew 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);
531627fcede3SMatthew G. Knepley       }
531727fcede3SMatthew G. Knepley #endif
531827fcede3SMatthew G. Knepley     }
531927fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
532027fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
532127fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
532227fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
532327fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
532427fcede3SMatthew G. Knepley 
532527fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
532627fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
532727fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
532827fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
532927fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
533027fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
533127fcede3SMatthew G. Knepley #if 1
533227fcede3SMatthew 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);
533327fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
533427fcede3SMatthew 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);
533527fcede3SMatthew G. Knepley       }
533627fcede3SMatthew G. Knepley #endif
533727fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0;
533827fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1;
533927fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
534027fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
534127fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
534227fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
534327fcede3SMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
534427fcede3SMatthew 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]);
5345d273725eSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2;
534627fcede3SMatthew G. Knepley       }
534727fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
534827fcede3SMatthew G. Knepley #if 1
534927fcede3SMatthew 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);
535027fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
535127fcede3SMatthew 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);
535227fcede3SMatthew G. Knepley       }
535327fcede3SMatthew G. Knepley #endif
535427fcede3SMatthew G. Knepley     }
535527fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
535627fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
535727fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
535827fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
535927fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size;
536027fcede3SMatthew G. Knepley 
536127fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
536227fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr);
536327fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr);
536427fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart);
536527fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart);
536627fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
536727fcede3SMatthew G. Knepley #if 1
536827fcede3SMatthew 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);
536927fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
537027fcede3SMatthew 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);
537127fcede3SMatthew G. Knepley       }
537227fcede3SMatthew G. Knepley #endif
537327fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0;
537427fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1;
537527fcede3SMatthew G. Knepley       supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2;
537627fcede3SMatthew G. Knepley       supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3;
537727fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
537827fcede3SMatthew G. Knepley #if 1
537927fcede3SMatthew 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);
538027fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
538127fcede3SMatthew 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);
538227fcede3SMatthew G. Knepley       }
538327fcede3SMatthew G. Knepley #endif
538427fcede3SMatthew G. Knepley     }
538527fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
538627fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
538727fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
538827fcede3SMatthew G. Knepley       const PetscInt *support, *cone;
538927fcede3SMatthew G. Knepley       PetscInt        size, s;
539027fcede3SMatthew G. Knepley 
539127fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
539227fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
539327fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
539427fcede3SMatthew G. Knepley         PetscInt r = 0;
539527fcede3SMatthew G. Knepley 
539627fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
539727fcede3SMatthew G. Knepley         if (cone[1] == v) r = 1;
539827fcede3SMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
539927fcede3SMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax);
540027fcede3SMatthew G. Knepley       }
540127fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
540227fcede3SMatthew G. Knepley #if 1
540327fcede3SMatthew 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);
540427fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
540527fcede3SMatthew 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);
540627fcede3SMatthew G. Knepley       }
540727fcede3SMatthew G. Knepley #endif
540827fcede3SMatthew G. Knepley     }
540927fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
541027fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
541127fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
541227fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
541327fcede3SMatthew G. Knepley       PetscInt        size, s;
541427fcede3SMatthew G. Knepley 
541527fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
541627fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
541727fcede3SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
541827fcede3SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
541927fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
542027fcede3SMatthew G. Knepley         PetscInt r;
542127fcede3SMatthew G. Knepley 
542227fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
542327fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
542427fcede3SMatthew G. Knepley         if (support[s] < fMax) {
542527fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r;
542627fcede3SMatthew G. Knepley         } else {
542727fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax);
542827fcede3SMatthew G. Knepley         }
542927fcede3SMatthew G. Knepley       }
543027fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
543127fcede3SMatthew G. Knepley #if 1
543227fcede3SMatthew 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);
543327fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
543427fcede3SMatthew 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);
543527fcede3SMatthew G. Knepley       }
543627fcede3SMatthew G. Knepley #endif
543727fcede3SMatthew G. Knepley     }
543827fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
543927fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
544027fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
544127fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
544227fcede3SMatthew G. Knepley       PetscInt        size, s;
544327fcede3SMatthew G. Knepley 
544427fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
544527fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
544627fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 +  (f - fStart)*4 + r;
544727fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
544827fcede3SMatthew G. Knepley         PetscInt r;
544927fcede3SMatthew G. Knepley 
545027fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
545127fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
545227fcede3SMatthew G. Knepley         if (support[s] < cMax) {
545327fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r;
545427fcede3SMatthew G. Knepley         } else {
545527fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax       - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax);
545627fcede3SMatthew G. Knepley         }
545727fcede3SMatthew G. Knepley       }
545827fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
545927fcede3SMatthew G. Knepley #if 1
546027fcede3SMatthew 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);
546127fcede3SMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
546227fcede3SMatthew 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);
546327fcede3SMatthew G. Knepley       }
546427fcede3SMatthew G. Knepley #endif
546527fcede3SMatthew G. Knepley     }
546627fcede3SMatthew G. Knepley     /* Cell vertices have 6 supports */
546727fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
546827fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
546927fcede3SMatthew G. Knepley       PetscInt       supportNew[6];
547027fcede3SMatthew G. Knepley 
547127fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
547227fcede3SMatthew G. Knepley         supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
547327fcede3SMatthew G. Knepley       }
547427fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
547527fcede3SMatthew G. Knepley     }
547627fcede3SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
547727fcede3SMatthew G. Knepley     break;
547875d3a19aSMatthew G. Knepley   default:
547975d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
548075d3a19aSMatthew G. Knepley   }
548175d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
548275d3a19aSMatthew G. Knepley }
548375d3a19aSMatthew G. Knepley 
548475d3a19aSMatthew G. Knepley #undef __FUNCT__
548575d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCoordinates"
548686150812SJed Brown static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
548775d3a19aSMatthew G. Knepley {
548875d3a19aSMatthew G. Knepley   PetscSection   coordSection, coordSectionNew;
548975d3a19aSMatthew G. Knepley   Vec            coordinates, coordinatesNew;
549075d3a19aSMatthew G. Knepley   PetscScalar   *coords, *coordsNew;
54913478d7aaSMatthew G. Knepley   const PetscInt numVertices = depthSize ? depthSize[0] : 0;
5492a57030b0SMatthew G. Knepley   PetscInt       dim, spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f;
549375d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
549475d3a19aSMatthew G. Knepley 
549575d3a19aSMatthew G. Knepley   PetscFunctionBegin;
5496a57030b0SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
549775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
549875d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
5499b5da9499SMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
550075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
550175d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
550227fcede3SMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr);
55033478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);}
550475d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);
5505f719d809SMatthew G. Knepley   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
5506f1d7821bSLawrence Mitchell   ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr);
550775d3a19aSMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr);
550875d3a19aSMatthew G. Knepley   ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr);
5509f1d7821bSLawrence Mitchell   ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr);
55103478d7aaSMatthew G. Knepley   ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr);
551127fcede3SMatthew G. Knepley   if (cMax < 0) cMax = cEnd;
551275d3a19aSMatthew G. Knepley   if (fMax < 0) fMax = fEnd;
5513b5da9499SMatthew G. Knepley   if (eMax < 0) eMax = eEnd;
5514f1d7821bSLawrence Mitchell   /* All vertices have the spaceDim coordinates */
55153478d7aaSMatthew G. Knepley   for (v = vStartNew; v < vStartNew+numVertices; ++v) {
5516f1d7821bSLawrence Mitchell     ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr);
5517f1d7821bSLawrence Mitchell     ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr);
551875d3a19aSMatthew G. Knepley   }
551975d3a19aSMatthew G. Knepley   ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr);
552046e270d4SMatthew G. Knepley   ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr);
552175d3a19aSMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
552275d3a19aSMatthew G. Knepley   ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr);
552375d3a19aSMatthew G. Knepley   ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr);
552475d3a19aSMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr);
552575d3a19aSMatthew G. Knepley   ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr);
552660b9e8a1SMatthew G. Knepley   ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr);
552760b9e8a1SMatthew G. Knepley   ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr);
552875d3a19aSMatthew G. Knepley   ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr);
552975d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr);
553075d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
5531b5da9499SMatthew G. Knepley   switch (refiner) {
55329b1a0e7fSLawrence Mitchell   case REFINER_NOOP: break;
55339b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
55349b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
5535b5da9499SMatthew G. Knepley     /* Face vertices have the average of corner coordinates */
5536d856d60fSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
553727fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
5538b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
5539b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
5540b5da9499SMatthew G. Knepley 
5541b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
5542b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
5543b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
5544b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
5545b5da9499SMatthew G. Knepley       }
5546b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
5547b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
5548b5da9499SMatthew G. Knepley       }
5549b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
5550f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
55512e17dfb7SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);}
5552f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
5553b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
5554b5da9499SMatthew G. Knepley     }
55559b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
55569b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
5557383c10e6SMatthew G. Knepley   case REFINER_SIMPLEX_1D:
5558b5da9499SMatthew G. Knepley     /* Cell vertices have the average of corner coordinates */
555927fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
55602ed5862eSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (dim > 1 ? (eMax - eStart) : 0) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0);
5561b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
5562b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
5563b5da9499SMatthew G. Knepley 
5564b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
5565b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
5566b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
5567b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
5568b5da9499SMatthew G. Knepley       }
5569b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
5570b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
5571b5da9499SMatthew G. Knepley       }
5572b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
5573f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
55742e17dfb7SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);}
5575f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
5576b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
5577b5da9499SMatthew G. Knepley     }
55789b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
55799b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
55809b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
55819b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
5582b5da9499SMatthew G. Knepley     /* Edge vertices have the average of endpoint coordinates */
5583b5da9499SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
5584b5da9499SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (e - eStart);
5585b5da9499SMatthew G. Knepley       const PetscInt *cone;
5586b5da9499SMatthew G. Knepley       PetscInt        coneSize, offA, offB, offnew, d;
5587b5da9499SMatthew G. Knepley 
5588b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr);
5589b5da9499SMatthew G. Knepley       if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize);
5590b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
5591b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr);
5592b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr);
5593b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
55942e17dfb7SMatthew G. Knepley       ierr = DMLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr);
5595f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) {
5596a96104c9SMatthew G. Knepley         coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]);
5597b5da9499SMatthew G. Knepley       }
5598b5da9499SMatthew G. Knepley     }
559975d3a19aSMatthew G. Knepley     /* Old vertices have the same coordinates */
560075d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
560175d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (v - vStart);
560275d3a19aSMatthew G. Knepley       PetscInt       off, offnew, d;
560375d3a19aSMatthew G. Knepley 
560475d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr);
560575d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
5606f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) {
560775d3a19aSMatthew G. Knepley         coordsNew[offnew+d] = coords[off+d];
560875d3a19aSMatthew G. Knepley       }
560975d3a19aSMatthew G. Knepley     }
5610b5da9499SMatthew G. Knepley     break;
5611b5da9499SMatthew G. Knepley   default:
5612b5da9499SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
561375d3a19aSMatthew G. Knepley   }
561475d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr);
561575d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
561675d3a19aSMatthew G. Knepley   ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr);
561775d3a19aSMatthew G. Knepley   ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr);
561875d3a19aSMatthew G. Knepley   ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr);
5619a96104c9SMatthew G. Knepley   if (dm->maxCell) {
5620a96104c9SMatthew G. Knepley     const PetscReal *maxCell, *L;
56215dc8c3f7SMatthew G. Knepley     const DMBoundaryType *bd;
56225dc8c3f7SMatthew G. Knepley     ierr = DMGetPeriodicity(dm,  &maxCell, &L, &bd);CHKERRQ(ierr);
56235dc8c3f7SMatthew G. Knepley     ierr = DMSetPeriodicity(rdm,  maxCell,  L,  bd);CHKERRQ(ierr);
5624a96104c9SMatthew G. Knepley   }
562575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
562675d3a19aSMatthew G. Knepley }
562775d3a19aSMatthew G. Knepley 
562875d3a19aSMatthew G. Knepley #undef __FUNCT__
562975d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexCreateProcessSF"
5630963fc26aSMatthew G. Knepley /*@
5631963fc26aSMatthew G. Knepley   DMPlexCreateProcessSF - Create an SF which just has process connectivity
5632963fc26aSMatthew G. Knepley 
5633963fc26aSMatthew G. Knepley   Collective on DM
5634963fc26aSMatthew G. Knepley 
5635963fc26aSMatthew G. Knepley   Input Parameters:
5636963fc26aSMatthew G. Knepley + dm      - The DM
5637963fc26aSMatthew G. Knepley - sfPoint - The PetscSF which encodes point connectivity
5638963fc26aSMatthew G. Knepley 
5639963fc26aSMatthew G. Knepley   Output Parameters:
5640963fc26aSMatthew G. Knepley + processRanks - A list of process neighbors, or NULL
5641963fc26aSMatthew G. Knepley - sfProcess    - An SF encoding the process connectivity, or NULL
5642963fc26aSMatthew G. Knepley 
5643963fc26aSMatthew G. Knepley   Level: developer
5644963fc26aSMatthew G. Knepley 
5645963fc26aSMatthew G. Knepley .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF()
5646963fc26aSMatthew G. Knepley @*/
5647963fc26aSMatthew G. Knepley PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
564875d3a19aSMatthew G. Knepley {
564975d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, l;
565075d3a19aSMatthew G. Knepley   const PetscInt    *localPoints;
565175d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
565275d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
565375d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
565475d3a19aSMatthew G. Knepley   PetscInt          *ranks, *ranksNew;
5655963fc26aSMatthew G. Knepley   PetscMPIInt        numProcs;
565675d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
565775d3a19aSMatthew G. Knepley 
565875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
5659963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5660963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2);
5661963fc26aSMatthew G. Knepley   if (processRanks) {PetscValidPointer(processRanks, 3);}
5662963fc26aSMatthew G. Knepley   if (sfProcess)    {PetscValidPointer(sfProcess, 4);}
5663963fc26aSMatthew G. Knepley   ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &numProcs);CHKERRQ(ierr);
566475d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
5665785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr);
566675d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
566775d3a19aSMatthew G. Knepley     ranks[l] = remotePoints[l].rank;
566875d3a19aSMatthew G. Knepley   }
566975d3a19aSMatthew G. Knepley   ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr);
5670785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr);
5671785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr);
5672785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr);
567375d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
567475d3a19aSMatthew G. Knepley     ranksNew[l]              = ranks[l];
567575d3a19aSMatthew G. Knepley     localPointsNew[l]        = l;
567675d3a19aSMatthew G. Knepley     remotePointsNew[l].index = 0;
567775d3a19aSMatthew G. Knepley     remotePointsNew[l].rank  = ranksNew[l];
567875d3a19aSMatthew G. Knepley   }
567975d3a19aSMatthew G. Knepley   ierr = PetscFree(ranks);CHKERRQ(ierr);
5680963fc26aSMatthew G. Knepley   if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);}
5681963fc26aSMatthew G. Knepley   else              {ierr = PetscFree(ranksNew);CHKERRQ(ierr);}
5682963fc26aSMatthew G. Knepley   if (sfProcess) {
568375d3a19aSMatthew G. Knepley     ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr);
5684963fc26aSMatthew G. Knepley     ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr);
568575d3a19aSMatthew G. Knepley     ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr);
5686963fc26aSMatthew G. Knepley     ierr = PetscSFSetGraph(*sfProcess, numProcs, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
5687963fc26aSMatthew G. Knepley   }
568875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
568975d3a19aSMatthew G. Knepley }
569075d3a19aSMatthew G. Knepley 
569175d3a19aSMatthew G. Knepley #undef __FUNCT__
569275d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateSF"
569386150812SJed Brown static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
569475d3a19aSMatthew G. Knepley {
569575d3a19aSMatthew G. Knepley   PetscSF            sf, sfNew, sfProcess;
569675d3a19aSMatthew G. Knepley   IS                 processRanks;
569775d3a19aSMatthew G. Knepley   MPI_Datatype       depthType;
569875d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, numLeavesNew = 0, l, m;
569975d3a19aSMatthew G. Knepley   const PetscInt    *localPoints, *neighbors;
570075d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
570175d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
570275d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
570375d3a19aSMatthew G. Knepley   PetscInt          *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew;
570437d81139SMatthew G. Knepley   PetscInt           ldepth, depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n;
57057ba685a0SMatthew G. Knepley   PetscInt           cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
570675d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
570775d3a19aSMatthew G. Knepley 
570875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
570975d3a19aSMatthew G. Knepley   ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr);
571037d81139SMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &ldepth);CHKERRQ(ierr);
571137d81139SMatthew G. Knepley   ierr = MPIU_Allreduce(&ldepth, &depth, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr);
571237d81139SMatthew G. Knepley   if ((ldepth >= 0) && (depth != ldepth)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent Plex depth %d != %d", ldepth, depth);
571375d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
571475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
571575d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
571675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
571775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
5718add09238SMatthew G. Knepley   cMax = cMax < 0 ? cEnd : cMax;
5719add09238SMatthew G. Knepley   fMax = fMax < 0 ? fEnd : fMax;
5720add09238SMatthew G. Knepley   eMax = eMax < 0 ? eEnd : eMax;
57213478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
572275d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
572375d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr);
5724add09238SMatthew G. Knepley   /* Calculate size of new SF */
572575d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
572675d3a19aSMatthew G. Knepley   if (numRoots < 0) PetscFunctionReturn(0);
572775d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
572875d3a19aSMatthew G. Knepley     const PetscInt p = localPoints[l];
572975d3a19aSMatthew G. Knepley 
573075d3a19aSMatthew G. Knepley     switch (refiner) {
57310314a74cSLawrence Mitchell     case REFINER_SIMPLEX_1D:
57320314a74cSLawrence Mitchell       if ((p >= vStart) && (p < vEnd)) {
57330314a74cSLawrence Mitchell         /* Interior vertices stay the same */
57340314a74cSLawrence Mitchell         ++numLeavesNew;
57350314a74cSLawrence Mitchell       } else if ((p >= cStart && p < cMax)) {
57360314a74cSLawrence Mitchell         /* Interior cells add new cells and interior vertices */
57370314a74cSLawrence Mitchell         numLeavesNew += 2 + 1;
57380314a74cSLawrence Mitchell       }
57390314a74cSLawrence Mitchell       break;
57409b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_2D:
57419b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_2D:
5742a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5743a97b51b8SMatthew G. Knepley         /* Interior vertices stay the same */
5744a97b51b8SMatthew G. Knepley         ++numLeavesNew;
5745a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
5746a97b51b8SMatthew G. Knepley         /* Interior faces add new faces and vertex */
5747a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
5748a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
5749a97b51b8SMatthew G. Knepley         /* Hybrid faces stay the same */
5750a97b51b8SMatthew G. Knepley         ++numLeavesNew;
5751a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
5752a97b51b8SMatthew G. Knepley         /* Interior cells add new cells and interior faces */
5753a97b51b8SMatthew G. Knepley         numLeavesNew += 4 + 3;
5754a97b51b8SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
5755a97b51b8SMatthew G. Knepley         /* Hybrid cells add new cells and hybrid face */
5756a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
5757a97b51b8SMatthew G. Knepley       }
5758a97b51b8SMatthew G. Knepley       break;
57599b1a0e7fSLawrence Mitchell     case REFINER_HEX_2D:
57609b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_2D:
5761a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5762a97b51b8SMatthew G. Knepley         /* Interior vertices stay the same */
5763a97b51b8SMatthew G. Knepley         ++numLeavesNew;
5764a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
5765a97b51b8SMatthew G. Knepley         /* Interior faces add new faces and vertex */
5766a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
5767a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
5768a97b51b8SMatthew G. Knepley         /* Hybrid faces stay the same */
5769a97b51b8SMatthew G. Knepley         ++numLeavesNew;
5770a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
5771a97b51b8SMatthew G. Knepley         /* Interior cells add new cells, interior faces, and vertex */
5772a97b51b8SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
5773a97b51b8SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
5774a97b51b8SMatthew G. Knepley         /* Hybrid cells add new cells and hybrid face */
5775a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
5776a97b51b8SMatthew G. Knepley       }
5777a97b51b8SMatthew G. Knepley       break;
57789b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_3D:
57799b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_3D:
57806ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
57816ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
57826ce3c06aSMatthew G. Knepley         ++numLeavesNew;
57836ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
57846ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
57856ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
57866ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
57876ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
57886ce3c06aSMatthew G. Knepley         ++numLeavesNew;
57896ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
57906ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
57916ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
57926ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
57936ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
57946ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
57956ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
57966ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
57976ce3c06aSMatthew G. Knepley         numLeavesNew += 8 + 8 + 1;
57986ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
57996ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
58006ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
58016ce3c06aSMatthew G. Knepley       }
58026ce3c06aSMatthew G. Knepley       break;
58039b1a0e7fSLawrence Mitchell     case REFINER_HEX_3D:
58049b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_3D:
580527fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
580627fcede3SMatthew G. Knepley         /* Old vertices stay the same */
580727fcede3SMatthew G. Knepley         ++numLeavesNew;
580827fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
580927fcede3SMatthew G. Knepley         /* Interior edges add new edges, and vertex */
581027fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
581127fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
581227fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
581327fcede3SMatthew G. Knepley         ++numLeavesNew;
581427fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
581527fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
581627fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
581727fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
581827fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
581927fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
582027fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
582127fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
582227fcede3SMatthew G. Knepley         numLeavesNew += 8 + 12 + 6 + 1;
582327fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
582427fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
582527fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
582627fcede3SMatthew G. Knepley       }
582727fcede3SMatthew G. Knepley       break;
582875d3a19aSMatthew G. Knepley     default:
582975d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
583075d3a19aSMatthew G. Knepley     }
583175d3a19aSMatthew G. Knepley   }
583275d3a19aSMatthew G. Knepley   /* Communicate depthSizes for each remote rank */
583375d3a19aSMatthew G. Knepley   ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr);
583475d3a19aSMatthew G. Knepley   ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr);
5835dcca6d9dSJed Brown   ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr);
5836dcca6d9dSJed Brown   ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr);
583775d3a19aSMatthew G. Knepley   ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr);
583875d3a19aSMatthew G. Knepley   ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr);
583975d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
584075d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
584175d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
584275d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr);
584375d3a19aSMatthew G. Knepley   }
584475d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cMax;
584575d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vMax;
584675d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fMax;
584775d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eMax;
584875d3a19aSMatthew G. Knepley 
584975d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
585075d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
585175d3a19aSMatthew G. Knepley 
585275d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cEnd - cStart;
585375d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vEnd - vStart;
585475d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fEnd - fStart;
585575d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eEnd - eStart;
585675d3a19aSMatthew G. Knepley 
585775d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
585875d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
585975d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
586075d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr);
58610252e7f5SMatthew 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];
58620252e7f5SMatthew 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];
58630252e7f5SMatthew 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];
586475d3a19aSMatthew G. Knepley   }
586575d3a19aSMatthew G. Knepley   ierr = MPI_Type_free(&depthType);CHKERRQ(ierr);
586675d3a19aSMatthew G. Knepley   ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr);
586775d3a19aSMatthew G. Knepley   /* Calculate new point SF */
5868785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr);
5869785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr);
587075d3a19aSMatthew G. Knepley   ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr);
587175d3a19aSMatthew G. Knepley   for (l = 0, m = 0; l < numLeaves; ++l) {
587275d3a19aSMatthew G. Knepley     PetscInt    p     = localPoints[l];
587375d3a19aSMatthew G. Knepley     PetscInt    rp    = remotePoints[l].index, n;
587475d3a19aSMatthew G. Knepley     PetscMPIInt rrank = remotePoints[l].rank;
587575d3a19aSMatthew G. Knepley 
587675d3a19aSMatthew G. Knepley     ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr);
587775d3a19aSMatthew G. Knepley     if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank);
587875d3a19aSMatthew G. Knepley     switch (refiner) {
58790314a74cSLawrence Mitchell     case REFINER_SIMPLEX_1D:
58800314a74cSLawrence Mitchell       if ((p >= vStart) && (p < vEnd)) {
58810314a74cSLawrence Mitchell         /* Old vertices stay the same */
58820314a74cSLawrence Mitchell         localPointsNew[m]        = vStartNew     + (p  - vStart);
58830314a74cSLawrence Mitchell         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
58840314a74cSLawrence Mitchell         remotePointsNew[m].rank  = rrank;
58850314a74cSLawrence Mitchell         ++m;
58860314a74cSLawrence Mitchell       } else if ((p >= cStart) && (p < cMax)) {
58870314a74cSLawrence Mitchell         /* Old interior cells add new cells and vertex */
58880314a74cSLawrence Mitchell         for (r = 0; r < 2; ++r, ++m) {
58890314a74cSLawrence Mitchell           localPointsNew[m]        = cStartNew     + (p  - cStart)*2     + r;
58900314a74cSLawrence Mitchell           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r;
58910314a74cSLawrence Mitchell           remotePointsNew[m].rank  = rrank;
58920314a74cSLawrence Mitchell         }
58930314a74cSLawrence Mitchell         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - cStart);
58940314a74cSLawrence Mitchell         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]);
58950314a74cSLawrence Mitchell         remotePointsNew[m].rank  = rrank;
58960314a74cSLawrence Mitchell         ++m;
58970314a74cSLawrence Mitchell       }
58980314a74cSLawrence Mitchell       break;
58999b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_2D:
59009b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_2D:
590175d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
590275d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
590375d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
590475d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
590575d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
590675d3a19aSMatthew G. Knepley         ++m;
590775d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
590875d3a19aSMatthew G. Knepley         /* Old interior faces add new faces and vertex */
590975d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
591075d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
591175d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
591275d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
591375d3a19aSMatthew G. Knepley         }
5914add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
5915add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
5916add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5917add09238SMatthew G. Knepley         ++m;
591875d3a19aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
591975d3a19aSMatthew G. Knepley         /* Old hybrid faces stay the same */
592075d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
592175d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
592275d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
592375d3a19aSMatthew G. Knepley         ++m;
592475d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
592575d3a19aSMatthew G. Knepley         /* Old interior cells add new cells and interior faces */
592675d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
592775d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
592875d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
592975d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
593075d3a19aSMatthew G. Knepley         }
593175d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
593275d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*3     + r;
593375d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r;
593475d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
593575d3a19aSMatthew G. Knepley         }
5936add09238SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
593775d3a19aSMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
593875d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
593975d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
594075d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
594175d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
594275d3a19aSMatthew G. Knepley         }
594375d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*3     + (p  - cMax);
594475d3a19aSMatthew 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]);
594575d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
594675d3a19aSMatthew G. Knepley         ++m;
594775d3a19aSMatthew G. Knepley       }
594875d3a19aSMatthew G. Knepley       break;
59499b1a0e7fSLawrence Mitchell     case REFINER_HEX_2D:
59509b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_2D:
5951a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5952a97b51b8SMatthew G. Knepley         /* Old vertices stay the same */
5953a97b51b8SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
5954a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
5955a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5956a97b51b8SMatthew G. Knepley         ++m;
5957a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
5958a97b51b8SMatthew G. Knepley         /* Old interior faces add new faces and vertex */
5959a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5960a97b51b8SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
5961a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
5962a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5963a97b51b8SMatthew G. Knepley         }
5964add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
5965add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
5966add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5967add09238SMatthew G. Knepley         ++m;
5968a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
5969a97b51b8SMatthew G. Knepley         /* Old hybrid faces stay the same */
5970a97b51b8SMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
5971a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
5972a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5973a97b51b8SMatthew G. Knepley         ++m;
5974a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
5975a97b51b8SMatthew G. Knepley         /* Old interior cells add new cells, interior faces, and vertex */
5976a97b51b8SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
5977a97b51b8SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
5978a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
5979a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5980a97b51b8SMatthew G. Knepley         }
5981a97b51b8SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
5982a97b51b8SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*4     + r;
5983a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r;
5984a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5985a97b51b8SMatthew G. Knepley         }
5986add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)               + (fMax                              - fStart)     + (p  - cStart);
5987add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0]  + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]);
5988add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5989add09238SMatthew G. Knepley         ++m;
5990a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
5991a97b51b8SMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
5992a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5993a97b51b8SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
5994a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
5995a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5996a97b51b8SMatthew G. Knepley         }
5997a97b51b8SMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*4     + (p  - cMax);
5998a97b51b8SMatthew 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]);
5999a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
6000a97b51b8SMatthew G. Knepley         ++m;
6001a97b51b8SMatthew G. Knepley       }
6002a97b51b8SMatthew G. Knepley       break;
60039b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_3D:
60049b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_3D:
60056ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
60066ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
60076ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
60086ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
60096ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
60106ce3c06aSMatthew G. Knepley         ++m;
60116ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
60126ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
60136ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
60146ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
60156ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
60166ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
60176ce3c06aSMatthew G. Knepley         }
60186ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
60196ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
60206ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
60216ce3c06aSMatthew G. Knepley         ++m;
60226ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
60236ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
60246ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (p  - eMax);
60257d5cd7d5SMatthew 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]);
60266ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
60276ce3c06aSMatthew G. Knepley         ++m;
60286ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
60296ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
60306ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
60316ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
60326ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
60336ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
60346ce3c06aSMatthew G. Knepley         }
60356ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
60366ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*3     + r;
60376ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r;
60386ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
60396ce3c06aSMatthew G. Knepley         }
60406ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
60416ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
60426ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
6043899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (p  - fMax)*2                              + r;
6044899f98d0SMatthew 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;
60456ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
60466ce3c06aSMatthew G. Knepley         }
60477d5cd7d5SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (eEnd                                    - eMax)                        + (p  - fMax);
60487d5cd7d5SMatthew 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]);
60496ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
605009b1338fSMatthew G. Knepley         ++m;
60516ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
60526ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
60536ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
60546ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
60556ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
60566ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
60576ce3c06aSMatthew G. Knepley         }
60586ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
60596ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*8     + r;
60606ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r;
60616ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
60626ce3c06aSMatthew G. Knepley         }
6063c7c54c77SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (p  - cStart)*1     + 0;
6064c7c54c77SMatthew 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;
60656ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
606609b1338fSMatthew G. Knepley         ++m;
60676ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
60686ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
60696ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
60706ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
60716ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
60726ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
60736ce3c06aSMatthew G. Knepley         }
60746ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
6075899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (fEnd                                          - fMax)*2                              + (p  - cMax)*3                            + r;
6076899f98d0SMatthew 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;
60776ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
60786ce3c06aSMatthew G. Knepley         }
60796ce3c06aSMatthew G. Knepley       }
60806ce3c06aSMatthew G. Knepley       break;
60819b1a0e7fSLawrence Mitchell     case REFINER_HEX_3D:
60829b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_3D:
608327fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
608427fcede3SMatthew G. Knepley         /* Interior vertices stay the same */
608527fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
608627fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
608727fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
608827fcede3SMatthew G. Knepley         ++m;
608927fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
609027fcede3SMatthew G. Knepley         /* Interior edges add new edges and vertex */
609127fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
609227fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
609327fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
609427fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
609527fcede3SMatthew G. Knepley         }
609627fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
609727fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
609827fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
609927fcede3SMatthew G. Knepley         ++m;
610027fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
610127fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
610227fcede3SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (p  - eMax);
6103d2701f60SMatthew 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]);
610427fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
610527fcede3SMatthew G. Knepley         ++m;
610627fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
610727fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
610827fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
610927fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
611027fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
611127fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
611227fcede3SMatthew G. Knepley         }
611327fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
611427fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*4     + r;
611527fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r;
611627fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
611727fcede3SMatthew G. Knepley         }
611827fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eMax                        - eStart)     + (p  - fStart);
611927fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]);
612027fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
612127fcede3SMatthew G. Knepley         ++m;
612227fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
612327fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
612427fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
6125d2701f60SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*12     + (p  - fMax)*2                              + r;
6126d2701f60SMatthew 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;
612727fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
612827fcede3SMatthew G. Knepley         }
6129d2701f60SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (eEnd                                    - eMax)                        + (p  - fMax);
6130d2701f60SMatthew 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]);
613127fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
613227fcede3SMatthew G. Knepley         ++m;
613327fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
613427fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
613527fcede3SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
613627fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
613727fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
613827fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
613927fcede3SMatthew G. Knepley         }
614027fcede3SMatthew G. Knepley         for (r = 0; r < 12; ++r, ++m) {
614127fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*12     + r;
614227fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r;
614327fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
614427fcede3SMatthew G. Knepley         }
614527fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r, ++m) {
614627fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (p  - cStart)*6     + r;
614727fcede3SMatthew 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;
614827fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
614927fcede3SMatthew G. Knepley         }
615027fcede3SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
615127fcede3SMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (eMax                        - eStart)     + (fMax                              - fStart)     + (p  - cStart)     + r;
615227fcede3SMatthew 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;
615327fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
615427fcede3SMatthew G. Knepley         }
615527fcede3SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
615627fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
615727fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
615827fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
615927fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
616027fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
616127fcede3SMatthew G. Knepley         }
616227fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
6163d2701f60SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*12     + (fEnd                                          - fMax)*2                              + (p  - cMax)*4                            + r;
6164d2701f60SMatthew 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;
616527fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
616627fcede3SMatthew G. Knepley         }
6167d2701f60SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (eEnd                                    - eMax)                        + (fEnd                                          - fMax)                              + (p  - cMax);
6168d2701f60SMatthew 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]);
616927fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
617027fcede3SMatthew G. Knepley         ++m;
617127fcede3SMatthew G. Knepley       }
617227fcede3SMatthew G. Knepley       break;
617375d3a19aSMatthew G. Knepley     default:
617475d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
617575d3a19aSMatthew G. Knepley     }
617675d3a19aSMatthew G. Knepley   }
617709b1338fSMatthew G. Knepley   if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew);
617875d3a19aSMatthew G. Knepley   ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr);
617975d3a19aSMatthew G. Knepley   ierr = ISDestroy(&processRanks);CHKERRQ(ierr);
6180ba3c3d50SMatthew G. Knepley   {
6181ba3c3d50SMatthew G. Knepley     PetscSFNode *rp, *rtmp;
6182ba3c3d50SMatthew G. Knepley     PetscInt    *lp, *idx, *ltmp, i;
6183ba3c3d50SMatthew G. Knepley 
6184ba3c3d50SMatthew G. Knepley     /* SF needs sorted leaves to correct calculate Gather */
6185ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr);
6186ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr);
6187ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr);
6188c7c54c77SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
6189c7c54c77SMatthew 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);
6190c7c54c77SMatthew G. Knepley       idx[i] = i;
6191c7c54c77SMatthew G. Knepley     }
6192ba3c3d50SMatthew G. Knepley     ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr);
6193ba3c3d50SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
6194ba3c3d50SMatthew G. Knepley       lp[i] = localPointsNew[idx[i]];
6195ba3c3d50SMatthew G. Knepley       rp[i] = remotePointsNew[idx[i]];
6196ba3c3d50SMatthew G. Knepley     }
6197ba3c3d50SMatthew G. Knepley     ltmp            = localPointsNew;
6198ba3c3d50SMatthew G. Knepley     localPointsNew  = lp;
6199ba3c3d50SMatthew G. Knepley     rtmp            = remotePointsNew;
6200ba3c3d50SMatthew G. Knepley     remotePointsNew = rp;
6201ba3c3d50SMatthew G. Knepley     ierr = PetscFree(idx);CHKERRQ(ierr);
6202ba3c3d50SMatthew G. Knepley     ierr = PetscFree(ltmp);CHKERRQ(ierr);
6203ba3c3d50SMatthew G. Knepley     ierr = PetscFree(rtmp);CHKERRQ(ierr);
6204ba3c3d50SMatthew G. Knepley   }
620575d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
620675d3a19aSMatthew G. Knepley   ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr);
620706a0ba2dSMatthew G. Knepley   ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr);
620875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
620975d3a19aSMatthew G. Knepley }
621075d3a19aSMatthew G. Knepley 
621175d3a19aSMatthew G. Knepley #undef __FUNCT__
621275d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateLabels"
621386150812SJed Brown static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
621475d3a19aSMatthew G. Knepley {
621575d3a19aSMatthew G. Knepley   PetscInt       numLabels, l;
62167ba685a0SMatthew G. Knepley   PetscInt       depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r;
62177ba685a0SMatthew G. Knepley   PetscInt       cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
621875d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
621975d3a19aSMatthew G. Knepley 
622075d3a19aSMatthew G. Knepley   PetscFunctionBegin;
622175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
622275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
622375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
622475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
6225d963de37SMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
62263478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
6227c58f1c22SToby Isaac   ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr);
622875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
622975d3a19aSMatthew G. Knepley   switch (refiner) {
62309b1a0e7fSLawrence Mitchell   case REFINER_NOOP:
62310314a74cSLawrence Mitchell   case REFINER_SIMPLEX_1D:
62329b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
62339b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
62349b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
62359b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
62369b1a0e7fSLawrence Mitchell     break;
62379b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
62389b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
623958b8852aSMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
62409b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
62419b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
624275d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
624375d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
62441e317b1dSMatthew G. Knepley     break;
62459b1a0e7fSLawrence Mitchell   default:
62469b1a0e7fSLawrence Mitchell     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
624775d3a19aSMatthew G. Knepley   }
624875d3a19aSMatthew G. Knepley   for (l = 0; l < numLabels; ++l) {
624975d3a19aSMatthew G. Knepley     DMLabel         label, labelNew;
625075d3a19aSMatthew G. Knepley     const char     *lname;
625175d3a19aSMatthew G. Knepley     PetscBool       isDepth;
625275d3a19aSMatthew G. Knepley     IS              valueIS;
625375d3a19aSMatthew G. Knepley     const PetscInt *values;
62545aa44df4SToby Isaac     PetscInt        defVal;
625575d3a19aSMatthew G. Knepley     PetscInt        numValues, val;
625675d3a19aSMatthew G. Knepley 
6257c58f1c22SToby Isaac     ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr);
625875d3a19aSMatthew G. Knepley     ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr);
625975d3a19aSMatthew G. Knepley     if (isDepth) continue;
6260c58f1c22SToby Isaac     ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr);
6261c58f1c22SToby Isaac     ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr);
6262c58f1c22SToby Isaac     ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr);
62635aa44df4SToby Isaac     ierr = DMLabelGetDefaultValue(label,&defVal);CHKERRQ(ierr);
62645aa44df4SToby Isaac     ierr = DMLabelSetDefaultValue(labelNew,defVal);CHKERRQ(ierr);
626575d3a19aSMatthew G. Knepley     ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr);
626675d3a19aSMatthew G. Knepley     ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr);
626775d3a19aSMatthew G. Knepley     ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr);
626875d3a19aSMatthew G. Knepley     for (val = 0; val < numValues; ++val) {
626975d3a19aSMatthew G. Knepley       IS              pointIS;
627075d3a19aSMatthew G. Knepley       const PetscInt *points;
627175d3a19aSMatthew G. Knepley       PetscInt        numPoints, n;
627275d3a19aSMatthew G. Knepley 
627375d3a19aSMatthew G. Knepley       ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr);
627475d3a19aSMatthew G. Knepley       ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);
627575d3a19aSMatthew G. Knepley       ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr);
62762bc5314cSMichael Lange       /* Ensure refined label is created with same number of strata as
62772bc5314cSMichael Lange        * original (even if no entries here). */
6278*ad8374ffSToby Isaac       ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr);
627975d3a19aSMatthew G. Knepley       for (n = 0; n < numPoints; ++n) {
628075d3a19aSMatthew G. Knepley         const PetscInt p = points[n];
628175d3a19aSMatthew G. Knepley         switch (refiner) {
62820314a74cSLawrence Mitchell         case REFINER_SIMPLEX_1D:
62830314a74cSLawrence Mitchell           if ((p >= vStart) && (p < vEnd)) {
62840314a74cSLawrence Mitchell             /* Old vertices stay the same */
62850314a74cSLawrence Mitchell             newp = vStartNew + (p - vStart);
62860314a74cSLawrence Mitchell             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
62870314a74cSLawrence Mitchell           } else if ((p >= cStart) && (p < cEnd)) {
62880314a74cSLawrence Mitchell             /* Old cells add new cells and vertex */
62890314a74cSLawrence Mitchell             newp = vStartNew + (vEnd - vStart) + (p - cStart);
62900314a74cSLawrence Mitchell             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
62910314a74cSLawrence Mitchell             for (r = 0; r < 2; ++r) {
62920314a74cSLawrence Mitchell               newp = cStartNew + (p - cStart)*2 + r;
62930314a74cSLawrence Mitchell               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
62940314a74cSLawrence Mitchell             }
62950314a74cSLawrence Mitchell           }
62960314a74cSLawrence Mitchell           break;
62979b1a0e7fSLawrence Mitchell         case REFINER_SIMPLEX_2D:
629875d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
629975d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
630075d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
630175d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
630275d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
630375d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
630475d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
630575d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
630675d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
630775d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
630875d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
630975d3a19aSMatthew G. Knepley             }
631075d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
631175d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces */
631275d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
631375d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
631475d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
631575d3a19aSMatthew G. Knepley             }
631675d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
631775d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
631875d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
631975d3a19aSMatthew G. Knepley             }
632075d3a19aSMatthew G. Knepley           }
632175d3a19aSMatthew G. Knepley           break;
63229b1a0e7fSLawrence Mitchell         case REFINER_HEX_2D:
632375d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
632475d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
632575d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
632675d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
632775d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
632875d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
632975d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
633075d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
633175d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
633275d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
633375d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
633475d3a19aSMatthew G. Knepley             }
633575d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
633675d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces and vertex */
633775d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
633875d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
633975d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
634075d3a19aSMatthew G. Knepley             }
634175d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
634275d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
634375d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
634475d3a19aSMatthew G. Knepley             }
634575d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
634675d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
634775d3a19aSMatthew G. Knepley           }
634875d3a19aSMatthew G. Knepley           break;
63499b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_SIMPLEX_2D:
635075d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
635175d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
635275d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
635375d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
635475d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
635575d3a19aSMatthew G. Knepley             /* Old interior faces add new faces and vertex */
635675d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
635775d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
635875d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
635975d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
636075d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
636175d3a19aSMatthew G. Knepley             }
636275d3a19aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
636375d3a19aSMatthew G. Knepley             /* Old hybrid faces stay the same */
636475d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
636575d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
636675d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
636775d3a19aSMatthew G. Knepley             /* Old interior cells add new cells and interior faces */
636875d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
636975d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
637075d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
637175d3a19aSMatthew G. Knepley             }
637275d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
637375d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
637475d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
637575d3a19aSMatthew G. Knepley             }
637675d3a19aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
637775d3a19aSMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
637875d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
637975d3a19aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
638075d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
638175d3a19aSMatthew G. Knepley             }
638275d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
638375d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
638475d3a19aSMatthew G. Knepley           }
638575d3a19aSMatthew G. Knepley           break;
63869b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_HEX_2D:
6387a97b51b8SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
6388a97b51b8SMatthew G. Knepley             /* Old vertices stay the same */
6389a97b51b8SMatthew G. Knepley             newp = vStartNew + (p - vStart);
6390a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6391a97b51b8SMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
6392a97b51b8SMatthew G. Knepley             /* Old interior faces add new faces and vertex */
6393a97b51b8SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
6394a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6395a97b51b8SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
6396a97b51b8SMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
6397a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6398a97b51b8SMatthew G. Knepley             }
6399a97b51b8SMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
6400a97b51b8SMatthew G. Knepley             /* Old hybrid faces stay the same */
6401a97b51b8SMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
6402a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6403a97b51b8SMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
6404a97b51b8SMatthew G. Knepley             /* Old interior cells add new cells, interior faces, and vertex */
6405a97b51b8SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
6406a97b51b8SMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
6407a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6408a97b51b8SMatthew G. Knepley             }
6409a97b51b8SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
6410a97b51b8SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
6411a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6412a97b51b8SMatthew G. Knepley             }
6413a97b51b8SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
6414a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6415a97b51b8SMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
6416a97b51b8SMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
6417a97b51b8SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
6418a97b51b8SMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
6419a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6420a97b51b8SMatthew G. Knepley             }
6421a97b51b8SMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax);
6422a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6423a97b51b8SMatthew G. Knepley           }
6424a97b51b8SMatthew G. Knepley           break;
64259b1a0e7fSLawrence Mitchell         case REFINER_SIMPLEX_3D:
6426b5da9499SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
6427b5da9499SMatthew G. Knepley             /* Old vertices stay the same */
6428b5da9499SMatthew G. Knepley             newp = vStartNew + (p - vStart);
6429b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6430b5da9499SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
6431b5da9499SMatthew G. Knepley             /* Old edges add new edges and vertex */
6432b5da9499SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
6433b5da9499SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
6434b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6435b5da9499SMatthew G. Knepley             }
6436b5da9499SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
6437b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6438b5da9499SMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
6439b5da9499SMatthew G. Knepley             /* Old faces add new faces and edges */
6440b5da9499SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
6441b5da9499SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
6442b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6443b5da9499SMatthew G. Knepley             }
6444b5da9499SMatthew G. Knepley             for (r = 0; r < 3; ++r) {
6445b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
6446b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6447b5da9499SMatthew G. Knepley             }
6448b5da9499SMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
6449b5da9499SMatthew G. Knepley             /* Old cells add new cells and interior faces and edges */
6450b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
6451b5da9499SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
6452b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6453b5da9499SMatthew G. Knepley             }
6454b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
6455b5da9499SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r;
6456b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6457b5da9499SMatthew G. Knepley             }
6458b5da9499SMatthew G. Knepley             for (r = 0; r < 1; ++r) {
6459b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r;
6460b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6461b5da9499SMatthew G. Knepley             }
6462b5da9499SMatthew G. Knepley           }
6463b5da9499SMatthew G. Knepley           break;
64649b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_SIMPLEX_3D:
64656ce3c06aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
64666ce3c06aSMatthew G. Knepley             /* Interior vertices stay the same */
64676ce3c06aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
64686ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64696ce3c06aSMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
64706ce3c06aSMatthew G. Knepley             /* Interior edges add new edges and vertex */
64716ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
64726ce3c06aSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
64736ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64746ce3c06aSMatthew G. Knepley             }
64756ce3c06aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
64766ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64776ce3c06aSMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
64786ce3c06aSMatthew G. Knepley             /* Hybrid edges stay the same */
64796ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
64806ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64816ce3c06aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
64826ce3c06aSMatthew G. Knepley             /* Interior faces add new faces and edges */
64836ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
64846ce3c06aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
64856ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64866ce3c06aSMatthew G. Knepley             }
64876ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
64886ce3c06aSMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
64896ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64906ce3c06aSMatthew G. Knepley             }
64916ce3c06aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
64926ce3c06aSMatthew G. Knepley             /* Hybrid faces add new faces and edges */
64936ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
64946ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
64956ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64966ce3c06aSMatthew G. Knepley             }
64976ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax);
64986ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64996ce3c06aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
65006ce3c06aSMatthew G. Knepley             /* Interior cells add new cells, faces, and edges */
65016ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
65026ce3c06aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
65036ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
65046ce3c06aSMatthew G. Knepley             }
65056ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
65066ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
65076ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
65086ce3c06aSMatthew G. Knepley             }
65096ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart);
65106ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
651158b8852aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
65126ce3c06aSMatthew G. Knepley             /* Hybrid cells add new cells and faces */
65136ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
65146ce3c06aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
65156ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
65166ce3c06aSMatthew G. Knepley             }
65176ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
65186ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
65196ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
65206ce3c06aSMatthew G. Knepley             }
65216ce3c06aSMatthew G. Knepley           }
65226ce3c06aSMatthew G. Knepley           break;
65239b1a0e7fSLawrence Mitchell         case REFINER_HEX_3D:
65242eabf88fSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
65252eabf88fSMatthew G. Knepley             /* Old vertices stay the same */
65262eabf88fSMatthew G. Knepley             newp = vStartNew + (p - vStart);
65272eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
652819d7d790SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
65292eabf88fSMatthew G. Knepley             /* Old edges add new edges and vertex */
65302eabf88fSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
65312eabf88fSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
65322eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
65332eabf88fSMatthew G. Knepley             }
65342eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
65352eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
65362eabf88fSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
65372eabf88fSMatthew G. Knepley             /* Old faces add new faces, edges, and vertex */
65382eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
65392eabf88fSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
65402eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
65412eabf88fSMatthew G. Knepley             }
65422eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
65432eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r;
65442eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
65452eabf88fSMatthew G. Knepley             }
65462eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart);
65472eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
65482eabf88fSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
65492eabf88fSMatthew G. Knepley             /* Old cells add new cells, faces, edges, and vertex */
65502eabf88fSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
65512eabf88fSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
65522eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
65532eabf88fSMatthew G. Knepley             }
65542eabf88fSMatthew G. Knepley             for (r = 0; r < 12; ++r) {
65552eabf88fSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r;
65562eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
65572eabf88fSMatthew G. Knepley             }
65582eabf88fSMatthew G. Knepley             for (r = 0; r < 6; ++r) {
65592eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r;
65602eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
65612eabf88fSMatthew G. Knepley             }
65622eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart);
65632eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
65642eabf88fSMatthew G. Knepley           }
65652eabf88fSMatthew G. Knepley           break;
65669b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_HEX_3D:
656727fcede3SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
656827fcede3SMatthew G. Knepley             /* Interior vertices stay the same */
656927fcede3SMatthew G. Knepley             newp = vStartNew + (p - vStart);
657027fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
657127fcede3SMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
657227fcede3SMatthew G. Knepley             /* Interior edges add new edges and vertex */
657327fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
657427fcede3SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
657527fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
657627fcede3SMatthew G. Knepley             }
657727fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
657827fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
657927fcede3SMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
658027fcede3SMatthew G. Knepley             /* Hybrid edges stay the same */
658127fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax);
658227fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
658327fcede3SMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
658427fcede3SMatthew G. Knepley             /* Interior faces add new faces, edges, and vertex */
658527fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
658627fcede3SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
658727fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
658827fcede3SMatthew G. Knepley             }
658927fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
659027fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r;
659127fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
659227fcede3SMatthew G. Knepley             }
659327fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
659427fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
659527fcede3SMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
659627fcede3SMatthew G. Knepley             /* Hybrid faces add new faces and edges */
659727fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
659827fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r;
659927fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
660027fcede3SMatthew G. Knepley             }
660127fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax);
660227fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
660327fcede3SMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
660427fcede3SMatthew G. Knepley             /* Interior cells add new cells, faces, edges, and vertex */
660527fcede3SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
660627fcede3SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
660727fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
660827fcede3SMatthew G. Knepley             }
660927fcede3SMatthew G. Knepley             for (r = 0; r < 12; ++r) {
661027fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r;
661127fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
661227fcede3SMatthew G. Knepley             }
661327fcede3SMatthew G. Knepley             for (r = 0; r < 6; ++r) {
661427fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r;
661527fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
661627fcede3SMatthew G. Knepley             }
661727fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart);
661827fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
661927fcede3SMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
662027fcede3SMatthew G. Knepley             /* Hybrid cells add new cells, faces, and edges */
662127fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
662227fcede3SMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
662327fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
662427fcede3SMatthew G. Knepley             }
662527fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
662627fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r;
662727fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
662827fcede3SMatthew G. Knepley             }
662927fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax);
663027fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
663127fcede3SMatthew G. Knepley           }
663227fcede3SMatthew G. Knepley           break;
663375d3a19aSMatthew G. Knepley         default:
663475d3a19aSMatthew G. Knepley           SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
663575d3a19aSMatthew G. Knepley         }
663675d3a19aSMatthew G. Knepley       }
663775d3a19aSMatthew G. Knepley       ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr);
663875d3a19aSMatthew G. Knepley       ierr = ISDestroy(&pointIS);CHKERRQ(ierr);
663975d3a19aSMatthew G. Knepley     }
664075d3a19aSMatthew G. Knepley     ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr);
664175d3a19aSMatthew G. Knepley     ierr = ISDestroy(&valueIS);CHKERRQ(ierr);
664275d3a19aSMatthew G. Knepley     if (0) {
664375d3a19aSMatthew G. Knepley       ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
664475d3a19aSMatthew G. Knepley     }
664575d3a19aSMatthew G. Knepley   }
664675d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
664775d3a19aSMatthew G. Knepley }
664875d3a19aSMatthew G. Knepley 
664975d3a19aSMatthew G. Knepley #undef __FUNCT__
6650509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexRefineUniform_Internal"
665175d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */
6652509c9b89SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined)
665375d3a19aSMatthew G. Knepley {
665475d3a19aSMatthew G. Knepley   DM             rdm;
665575d3a19aSMatthew G. Knepley   PetscInt      *depthSize;
665675d3a19aSMatthew G. Knepley   PetscInt       dim, depth = 0, d, pStart = 0, pEnd = 0;
665775d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
665875d3a19aSMatthew G. Knepley 
665975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
666075d3a19aSMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr);
666175d3a19aSMatthew G. Knepley   ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr);
6662c73cfb54SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
6663c73cfb54SMatthew G. Knepley   ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr);
666475d3a19aSMatthew G. Knepley   /* Calculate number of new points of each depth */
666575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
66661e573d11SMatthew G. Knepley   if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement");
6667854ce69bSBarry Smith   ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr);
666875d3a19aSMatthew G. Knepley   ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr);
666975d3a19aSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
667075d3a19aSMatthew G. Knepley   /* Step 1: Set chart */
667175d3a19aSMatthew G. Knepley   for (d = 0; d <= depth; ++d) pEnd += depthSize[d];
667275d3a19aSMatthew G. Knepley   ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr);
667375d3a19aSMatthew G. Knepley   /* Step 2: Set cone/support sizes */
667475d3a19aSMatthew G. Knepley   ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
667575d3a19aSMatthew G. Knepley   /* Step 3: Setup refined DM */
667675d3a19aSMatthew G. Knepley   ierr = DMSetUp(rdm);CHKERRQ(ierr);
667775d3a19aSMatthew G. Knepley   /* Step 4: Set cones and supports */
667875d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
667975d3a19aSMatthew G. Knepley   /* Step 5: Stratify */
668075d3a19aSMatthew G. Knepley   ierr = DMPlexStratify(rdm);CHKERRQ(ierr);
66810fadad52SMatthew G. Knepley   /* Step 6: Create pointSF */
668275d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
66830fadad52SMatthew G. Knepley   /* Step 7: Set coordinates for vertices */
66840fadad52SMatthew G. Knepley   ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
668575d3a19aSMatthew G. Knepley   /* Step 8: Create labels */
668675d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
668775d3a19aSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
668875d3a19aSMatthew G. Knepley 
668975d3a19aSMatthew G. Knepley   *dmRefined = rdm;
669075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
669175d3a19aSMatthew G. Knepley }
669275d3a19aSMatthew G. Knepley 
669375d3a19aSMatthew G. Knepley #undef __FUNCT__
66942389894bSMatthew G. Knepley #define __FUNCT__ "DMPlexCreateCoarsePointIS"
66952389894bSMatthew G. Knepley /*@
66962389894bSMatthew G. Knepley   DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data
66972389894bSMatthew G. Knepley 
66982389894bSMatthew G. Knepley   Input Parameter:
66992389894bSMatthew G. Knepley . dm - The coarse DM
67002389894bSMatthew G. Knepley 
67012389894bSMatthew G. Knepley   Output Parameter:
67022389894bSMatthew G. Knepley . fpointIS - The IS of all the fine points which exist in the original coarse mesh
67032389894bSMatthew G. Knepley 
67042389894bSMatthew G. Knepley   Level: developer
67052389894bSMatthew G. Knepley 
67062389894bSMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS()
67072389894bSMatthew G. Knepley @*/
67082389894bSMatthew G. Knepley PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS)
67092389894bSMatthew G. Knepley {
67102389894bSMatthew G. Knepley   CellRefiner    cellRefiner;
67112389894bSMatthew G. Knepley   PetscInt      *depthSize, *fpoints;
67122389894bSMatthew G. Knepley   PetscInt       cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
67132389894bSMatthew G. Knepley   PetscInt       depth, pStart, pEnd, p, vStart, vEnd, v;
67142389894bSMatthew G. Knepley   PetscErrorCode ierr;
67152389894bSMatthew G. Knepley 
67162389894bSMatthew G. Knepley   PetscFunctionBegin;
67172389894bSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
67182389894bSMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
67192389894bSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
67202389894bSMatthew G. Knepley   ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr);
6721854ce69bSBarry Smith   ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr);
67222389894bSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
67232389894bSMatthew G. Knepley   if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
67242389894bSMatthew G. Knepley   ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr);
67252389894bSMatthew G. Knepley   for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1;
67262389894bSMatthew G. Knepley   switch (cellRefiner) {
67276c0c04f5SMatthew G. Knepley   case REFINER_SIMPLEX_1D:
67286c0c04f5SMatthew G. Knepley   case REFINER_SIMPLEX_2D:
67296c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_SIMPLEX_2D:
67306c0c04f5SMatthew G. Knepley   case REFINER_HEX_2D:
67316c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_HEX_2D:
67326c0c04f5SMatthew G. Knepley   case REFINER_SIMPLEX_3D:
67336c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_SIMPLEX_3D:
67346c0c04f5SMatthew G. Knepley   case REFINER_HEX_3D:
67356c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_HEX_3D:
67362389894bSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart);
67372389894bSMatthew G. Knepley     break;
67382389894bSMatthew G. Knepley   default:
67392389894bSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", cellRefiner);
67402389894bSMatthew G. Knepley   }
67412389894bSMatthew G. Knepley   ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr);
67422389894bSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
67432389894bSMatthew G. Knepley   PetscFunctionReturn(0);
67442389894bSMatthew G. Knepley }
67452389894bSMatthew G. Knepley 
67462389894bSMatthew G. Knepley #undef __FUNCT__
674775d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementUniform"
67480e2b6761SMatthew G. Knepley /*@
67490e2b6761SMatthew G. Knepley   DMPlexSetRefinementUniform - Set the flag for uniform refinement
67500e2b6761SMatthew G. Knepley 
67510e2b6761SMatthew G. Knepley   Input Parameters:
67520e2b6761SMatthew G. Knepley + dm - The DM
67530e2b6761SMatthew G. Knepley - refinementUniform - The flag for uniform refinement
67540e2b6761SMatthew G. Knepley 
67550e2b6761SMatthew G. Knepley   Level: developer
67560e2b6761SMatthew G. Knepley 
67570e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
67580e2b6761SMatthew G. Knepley @*/
675975d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
676075d3a19aSMatthew G. Knepley {
676175d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
676275d3a19aSMatthew G. Knepley 
676375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
676475d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
676575d3a19aSMatthew G. Knepley   mesh->refinementUniform = refinementUniform;
676675d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
676775d3a19aSMatthew G. Knepley }
676875d3a19aSMatthew G. Knepley 
676975d3a19aSMatthew G. Knepley #undef __FUNCT__
677075d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementUniform"
67710e2b6761SMatthew G. Knepley /*@
67720e2b6761SMatthew G. Knepley   DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement
67730e2b6761SMatthew G. Knepley 
67740e2b6761SMatthew G. Knepley   Input Parameter:
67750e2b6761SMatthew G. Knepley . dm - The DM
67760e2b6761SMatthew G. Knepley 
67770e2b6761SMatthew G. Knepley   Output Parameter:
67780e2b6761SMatthew G. Knepley . refinementUniform - The flag for uniform refinement
67790e2b6761SMatthew G. Knepley 
67800e2b6761SMatthew G. Knepley   Level: developer
67810e2b6761SMatthew G. Knepley 
67820e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
67830e2b6761SMatthew G. Knepley @*/
678475d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
678575d3a19aSMatthew G. Knepley {
678675d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
678775d3a19aSMatthew G. Knepley 
678875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
678975d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
679075d3a19aSMatthew G. Knepley   PetscValidPointer(refinementUniform,  2);
679175d3a19aSMatthew G. Knepley   *refinementUniform = mesh->refinementUniform;
679275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
679375d3a19aSMatthew G. Knepley }
679475d3a19aSMatthew G. Knepley 
679575d3a19aSMatthew G. Knepley #undef __FUNCT__
679675d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementLimit"
67970e2b6761SMatthew G. Knepley /*@
67980e2b6761SMatthew G. Knepley   DMPlexSetRefinementLimit - Set the maximum cell volume for refinement
67990e2b6761SMatthew G. Knepley 
68000e2b6761SMatthew G. Knepley   Input Parameters:
68010e2b6761SMatthew G. Knepley + dm - The DM
68020e2b6761SMatthew G. Knepley - refinementLimit - The maximum cell volume in the refined mesh
68030e2b6761SMatthew G. Knepley 
68040e2b6761SMatthew G. Knepley   Level: developer
68050e2b6761SMatthew G. Knepley 
68060e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
68070e2b6761SMatthew G. Knepley @*/
680875d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
680975d3a19aSMatthew G. Knepley {
681075d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
681175d3a19aSMatthew G. Knepley 
681275d3a19aSMatthew G. Knepley   PetscFunctionBegin;
681375d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
681475d3a19aSMatthew G. Knepley   mesh->refinementLimit = refinementLimit;
681575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
681675d3a19aSMatthew G. Knepley }
681775d3a19aSMatthew G. Knepley 
681875d3a19aSMatthew G. Knepley #undef __FUNCT__
681975d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementLimit"
68200e2b6761SMatthew G. Knepley /*@
68210e2b6761SMatthew G. Knepley   DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement
68220e2b6761SMatthew G. Knepley 
68230e2b6761SMatthew G. Knepley   Input Parameter:
68240e2b6761SMatthew G. Knepley . dm - The DM
68250e2b6761SMatthew G. Knepley 
68260e2b6761SMatthew G. Knepley   Output Parameter:
68270e2b6761SMatthew G. Knepley . refinementLimit - The maximum cell volume in the refined mesh
68280e2b6761SMatthew G. Knepley 
68290e2b6761SMatthew G. Knepley   Level: developer
68300e2b6761SMatthew G. Knepley 
68310e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
68320e2b6761SMatthew G. Knepley @*/
683375d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
683475d3a19aSMatthew G. Knepley {
683575d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
683675d3a19aSMatthew G. Knepley 
683775d3a19aSMatthew G. Knepley   PetscFunctionBegin;
683875d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
683975d3a19aSMatthew G. Knepley   PetscValidPointer(refinementLimit,  2);
684075d3a19aSMatthew G. Knepley   /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
684175d3a19aSMatthew G. Knepley   *refinementLimit = mesh->refinementLimit;
684275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
684375d3a19aSMatthew G. Knepley }
684475d3a19aSMatthew G. Knepley 
684575d3a19aSMatthew G. Knepley #undef __FUNCT__
6846b28003e6SMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementFunction"
6847b28003e6SMatthew G. Knepley /*@
6848b28003e6SMatthew G. Knepley   DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement
6849b28003e6SMatthew G. Knepley 
6850b28003e6SMatthew G. Knepley   Input Parameters:
6851b28003e6SMatthew G. Knepley + dm - The DM
6852b28003e6SMatthew G. Knepley - refinementFunc - Function giving the maximum cell volume in the refined mesh
6853b28003e6SMatthew G. Knepley 
6854b28003e6SMatthew G. Knepley   Note: The calling sequence is refinementFunc(coords, limit)
6855b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid
6856b28003e6SMatthew G. Knepley $ limit  - The maximum cell volume for a cell containing this point
6857b28003e6SMatthew G. Knepley 
6858b28003e6SMatthew G. Knepley   Level: developer
6859b28003e6SMatthew G. Knepley 
6860b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
6861b28003e6SMatthew G. Knepley @*/
6862b28003e6SMatthew G. Knepley PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *))
6863b28003e6SMatthew G. Knepley {
6864b28003e6SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
6865b28003e6SMatthew G. Knepley 
6866b28003e6SMatthew G. Knepley   PetscFunctionBegin;
6867b28003e6SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6868b28003e6SMatthew G. Knepley   mesh->refinementFunc = refinementFunc;
6869b28003e6SMatthew G. Knepley   PetscFunctionReturn(0);
6870b28003e6SMatthew G. Knepley }
6871b28003e6SMatthew G. Knepley 
6872b28003e6SMatthew G. Knepley #undef __FUNCT__
687382169f37SMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementFunction"
6874b28003e6SMatthew G. Knepley /*@
6875b28003e6SMatthew G. Knepley   DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement
6876b28003e6SMatthew G. Knepley 
6877b28003e6SMatthew G. Knepley   Input Parameter:
6878b28003e6SMatthew G. Knepley . dm - The DM
6879b28003e6SMatthew G. Knepley 
6880b28003e6SMatthew G. Knepley   Output Parameter:
6881b28003e6SMatthew G. Knepley . refinementFunc - Function giving the maximum cell volume in the refined mesh
6882b28003e6SMatthew G. Knepley 
6883b28003e6SMatthew G. Knepley   Note: The calling sequence is refinementFunc(coords, limit)
6884b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid
6885b28003e6SMatthew G. Knepley $ limit  - The maximum cell volume for a cell containing this point
6886b28003e6SMatthew G. Knepley 
6887b28003e6SMatthew G. Knepley   Level: developer
6888b28003e6SMatthew G. Knepley 
6889b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
6890b28003e6SMatthew G. Knepley @*/
6891b28003e6SMatthew G. Knepley PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *))
6892b28003e6SMatthew G. Knepley {
6893b28003e6SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
6894b28003e6SMatthew G. Knepley 
6895b28003e6SMatthew G. Knepley   PetscFunctionBegin;
6896b28003e6SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6897b28003e6SMatthew G. Knepley   PetscValidPointer(refinementFunc,  2);
6898b28003e6SMatthew G. Knepley   *refinementFunc = mesh->refinementFunc;
6899b28003e6SMatthew G. Knepley   PetscFunctionReturn(0);
6900b28003e6SMatthew G. Knepley }
6901b28003e6SMatthew G. Knepley 
6902b28003e6SMatthew G. Knepley #undef __FUNCT__
6903509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexGetCellRefiner_Internal"
6904509c9b89SMatthew G. Knepley PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner)
690575d3a19aSMatthew G. Knepley {
69060f9259d6SMatthew G. Knepley   PetscInt       dim, cStart, cEnd, coneSize, cMax, fMax;
690775d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
690875d3a19aSMatthew G. Knepley 
690975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
6910c73cfb54SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
69113478d7aaSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
69129b1a0e7fSLawrence Mitchell   if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; PetscFunctionReturn(0);}
691375d3a19aSMatthew G. Knepley   ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr);
691489b38ed4SMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, NULL, NULL);CHKERRQ(ierr);
691575d3a19aSMatthew G. Knepley   switch (dim) {
69160314a74cSLawrence Mitchell   case 1:
69170314a74cSLawrence Mitchell     switch (coneSize) {
69180314a74cSLawrence Mitchell     case 2:
69190314a74cSLawrence Mitchell       *cellRefiner = REFINER_SIMPLEX_1D;
69200314a74cSLawrence Mitchell       break;
69210314a74cSLawrence Mitchell     default:
69220314a74cSLawrence Mitchell       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
69230314a74cSLawrence Mitchell     }
69240314a74cSLawrence Mitchell     break;
692575d3a19aSMatthew G. Knepley   case 2:
692675d3a19aSMatthew G. Knepley     switch (coneSize) {
692775d3a19aSMatthew G. Knepley     case 3:
69289b1a0e7fSLawrence Mitchell       if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_2D;
69299b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_SIMPLEX_2D;
693075d3a19aSMatthew G. Knepley       break;
693175d3a19aSMatthew G. Knepley     case 4:
693289b38ed4SMatthew G. Knepley       if (cMax >= 0 && fMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_2D;
69339b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_HEX_2D;
693475d3a19aSMatthew G. Knepley       break;
693575d3a19aSMatthew G. Knepley     default:
693675d3a19aSMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
693775d3a19aSMatthew G. Knepley     }
693875d3a19aSMatthew G. Knepley     break;
6939b5da9499SMatthew G. Knepley   case 3:
6940b5da9499SMatthew G. Knepley     switch (coneSize) {
6941b5da9499SMatthew G. Knepley     case 4:
69429b1a0e7fSLawrence Mitchell       if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D;
69439b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_SIMPLEX_3D;
6944b5da9499SMatthew G. Knepley       break;
69452eabf88fSMatthew G. Knepley     case 6:
69469b1a0e7fSLawrence Mitchell       if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_3D;
69479b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_HEX_3D;
69482eabf88fSMatthew G. Knepley       break;
6949b5da9499SMatthew G. Knepley     default:
6950b5da9499SMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
6951b5da9499SMatthew G. Knepley     }
6952b5da9499SMatthew G. Knepley     break;
695375d3a19aSMatthew G. Knepley   default:
695475d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim);
695575d3a19aSMatthew G. Knepley   }
695675d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
695775d3a19aSMatthew G. Knepley }
6958