xref: /petsc/src/dm/impls/plex/plexrefine.c (revision e53375922a6f5ddf331bb8e144d248f0354459b7)
1af0996ceSBarry Smith #include <petsc/private/dmpleximpl.h>   /*I      "petscdmplex.h"   I*/
275d3a19aSMatthew G. Knepley #include <petscsf.h>
375d3a19aSMatthew G. Knepley 
475d3a19aSMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode GetDepthStart_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cStart, PetscInt *fStart, PetscInt *eStart, PetscInt *vStart)
575d3a19aSMatthew G. Knepley {
675d3a19aSMatthew G. Knepley   PetscFunctionBegin;
775d3a19aSMatthew G. Knepley   if (cStart) *cStart = 0;
815fa1f8eSMatthew G. Knepley   if (vStart) *vStart = depth < 0 ? 0 : depthSize[depth];
915fa1f8eSMatthew G. Knepley   if (fStart) *fStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0];
1015fa1f8eSMatthew G. Knepley   if (eStart) *eStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1];
1175d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
1275d3a19aSMatthew G. Knepley }
1375d3a19aSMatthew G. Knepley 
1475d3a19aSMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode GetDepthEnd_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cEnd, PetscInt *fEnd, PetscInt *eEnd, PetscInt *vEnd)
1575d3a19aSMatthew G. Knepley {
1675d3a19aSMatthew G. Knepley   PetscFunctionBegin;
1715fa1f8eSMatthew G. Knepley   if (cEnd) *cEnd = depth < 0 ? 0 : depthSize[depth];
1815fa1f8eSMatthew G. Knepley   if (vEnd) *vEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0];
1915fa1f8eSMatthew G. Knepley   if (fEnd) *fEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1];
2015fa1f8eSMatthew G. Knepley   if (eEnd) *eEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1] + depthSize[1];
2175d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
2275d3a19aSMatthew G. Knepley }
2375d3a19aSMatthew G. Knepley 
24bed052eaSMatthew G. Knepley /* Gets the affine map from the original cell to each subcell */
25bed052eaSMatthew G. Knepley PetscErrorCode CellRefinerGetAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[])
26bed052eaSMatthew G. Knepley {
27bed052eaSMatthew G. Knepley   PetscReal     *v = NULL, *j = NULL, *invj = NULL, detJ;
28bed052eaSMatthew G. Knepley   PetscInt       dim, s;
29bed052eaSMatthew G. Knepley   PetscErrorCode ierr;
30bed052eaSMatthew G. Knepley 
31bed052eaSMatthew G. Knepley   PetscFunctionBegin;
32bed052eaSMatthew G. Knepley   switch (refiner) {
339b1a0e7fSLawrence Mitchell   case REFINER_NOOP: break;
349b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
35260b6d3fSMatthew G. Knepley     /*
36260b6d3fSMatthew G. Knepley      2
37260b6d3fSMatthew G. Knepley      |\
38260b6d3fSMatthew G. Knepley      | \
39260b6d3fSMatthew G. Knepley      |  \
40260b6d3fSMatthew G. Knepley      |   \
41260b6d3fSMatthew G. Knepley      | C  \
42260b6d3fSMatthew G. Knepley      |     \
43260b6d3fSMatthew G. Knepley      |      \
44260b6d3fSMatthew G. Knepley      2---1---1
45260b6d3fSMatthew G. Knepley      |\  D  / \
46260b6d3fSMatthew G. Knepley      | 2   0   \
47260b6d3fSMatthew G. Knepley      |A \ /  B  \
48260b6d3fSMatthew G. Knepley      0---0-------1
49260b6d3fSMatthew G. Knepley      */
50bed052eaSMatthew G. Knepley     dim = 2;
51bed052eaSMatthew G. Knepley     if (numSubcells) *numSubcells = 4;
52bed052eaSMatthew G. Knepley     if (v0) {
53bed052eaSMatthew G. Knepley       ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr);
54bed052eaSMatthew G. Knepley       /* A */
55bed052eaSMatthew G. Knepley       v[0+0] = -1.0; v[0+1] = -1.0;
56bed052eaSMatthew G. Knepley       j[0+0] =  0.5; j[0+1] =  0.0;
57bed052eaSMatthew G. Knepley       j[0+2] =  0.0; j[0+3] =  0.5;
58bed052eaSMatthew G. Knepley       /* B */
59bed052eaSMatthew G. Knepley       v[2+0] =  0.0; v[2+1] = -1.0;
60bed052eaSMatthew G. Knepley       j[4+0] =  0.5; j[4+1] =  0.0;
61bed052eaSMatthew G. Knepley       j[4+2] =  0.0; j[4+3] =  0.5;
62bed052eaSMatthew G. Knepley       /* C */
63bed052eaSMatthew G. Knepley       v[4+0] = -1.0; v[4+1] =  0.0;
64bed052eaSMatthew G. Knepley       j[8+0] =  0.5; j[8+1] =  0.0;
65bed052eaSMatthew G. Knepley       j[8+2] =  0.0; j[8+3] =  0.5;
66bed052eaSMatthew G. Knepley       /* D */
67bed052eaSMatthew G. Knepley       v[6+0]  =  0.0; v[6+1]  = -1.0;
68bed052eaSMatthew G. Knepley       j[12+0] =  0.0; j[12+1] = -0.5;
69bed052eaSMatthew G. Knepley       j[12+2] =  0.5; j[12+3] =  0.5;
70bed052eaSMatthew G. Knepley       for (s = 0; s < 4; ++s) {
71bed052eaSMatthew G. Knepley         DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]);
72bed052eaSMatthew G. Knepley         DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ);
73bed052eaSMatthew G. Knepley       }
74bed052eaSMatthew G. Knepley     }
75bed052eaSMatthew G. Knepley     break;
769b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
77260b6d3fSMatthew G. Knepley     /*
78260b6d3fSMatthew G. Knepley      3---------2---------2
79260b6d3fSMatthew G. Knepley      |         |         |
80260b6d3fSMatthew G. Knepley      |    D    2    C    |
81260b6d3fSMatthew G. Knepley      |         |         |
82260b6d3fSMatthew G. Knepley      3----3----0----1----1
83260b6d3fSMatthew G. Knepley      |         |         |
84260b6d3fSMatthew G. Knepley      |    A    0    B    |
85260b6d3fSMatthew G. Knepley      |         |         |
86260b6d3fSMatthew G. Knepley      0---------0---------1
87260b6d3fSMatthew G. Knepley      */
88260b6d3fSMatthew G. Knepley     dim = 2;
89260b6d3fSMatthew G. Knepley     if (numSubcells) *numSubcells = 4;
90260b6d3fSMatthew G. Knepley     if (v0) {
91260b6d3fSMatthew G. Knepley       ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr);
92260b6d3fSMatthew G. Knepley       /* A */
93260b6d3fSMatthew G. Knepley       v[0+0] = -1.0; v[0+1] = -1.0;
94260b6d3fSMatthew G. Knepley       j[0+0] =  0.5; j[0+1] =  0.0;
95260b6d3fSMatthew G. Knepley       j[0+2] =  0.0; j[0+3] =  0.5;
96260b6d3fSMatthew G. Knepley       /* B */
97260b6d3fSMatthew G. Knepley       v[2+0] =  0.0; v[2+1] = -1.0;
98260b6d3fSMatthew G. Knepley       j[4+0] =  0.5; j[4+1] =  0.0;
99260b6d3fSMatthew G. Knepley       j[4+2] =  0.0; j[4+3] =  0.5;
100260b6d3fSMatthew G. Knepley       /* C */
101260b6d3fSMatthew G. Knepley       v[4+0] =  0.0; v[4+1] =  0.0;
102260b6d3fSMatthew G. Knepley       j[8+0] =  0.5; j[8+1] =  0.0;
103260b6d3fSMatthew G. Knepley       j[8+2] =  0.0; j[8+3] =  0.5;
104260b6d3fSMatthew G. Knepley       /* D */
105260b6d3fSMatthew G. Knepley       v[6+0]  = -1.0; v[6+1]  =  0.0;
106260b6d3fSMatthew G. Knepley       j[12+0] =  0.5; j[12+1] =  0.0;
107260b6d3fSMatthew G. Knepley       j[12+2] =  0.0; j[12+3] =  0.5;
108260b6d3fSMatthew G. Knepley       for (s = 0; s < 4; ++s) {
109260b6d3fSMatthew G. Knepley         DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]);
110260b6d3fSMatthew G. Knepley         DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ);
111260b6d3fSMatthew G. Knepley       }
112260b6d3fSMatthew G. Knepley     }
113260b6d3fSMatthew G. Knepley     break;
114bed052eaSMatthew G. Knepley   default:
115bed052eaSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
116bed052eaSMatthew G. Knepley   }
117bed052eaSMatthew G. Knepley   if (v0) {*v0 = v; *jac = j; *invjac = invj;}
118bed052eaSMatthew G. Knepley   PetscFunctionReturn(0);
119bed052eaSMatthew G. Knepley }
120bed052eaSMatthew G. Knepley 
121bed052eaSMatthew G. Knepley PetscErrorCode CellRefinerRestoreAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[])
122bed052eaSMatthew G. Knepley {
123bed052eaSMatthew G. Knepley   PetscErrorCode ierr;
124bed052eaSMatthew G. Knepley 
125bed052eaSMatthew G. Knepley   PetscFunctionBegin;
126bed052eaSMatthew G. Knepley   ierr = PetscFree3(*v0,*jac,*invjac);CHKERRQ(ierr);
127bed052eaSMatthew G. Knepley   PetscFunctionReturn(0);
128bed052eaSMatthew G. Knepley }
129bed052eaSMatthew G. Knepley 
13080389061SMatthew G. Knepley /* Should this be here or in the DualSpace somehow? */
13180389061SMatthew G. Knepley PetscErrorCode CellRefinerInCellTest_Internal(CellRefiner refiner, const PetscReal point[], PetscBool *inside)
13280389061SMatthew G. Knepley {
13380389061SMatthew G. Knepley   PetscReal sum = 0.0;
13480389061SMatthew G. Knepley   PetscInt  d;
13580389061SMatthew G. Knepley 
13680389061SMatthew G. Knepley   PetscFunctionBegin;
13780389061SMatthew G. Knepley   *inside = PETSC_TRUE;
13880389061SMatthew G. Knepley   switch (refiner) {
1399b1a0e7fSLawrence Mitchell   case REFINER_NOOP: break;
1406c0c04f5SMatthew G. Knepley   case REFINER_SIMPLEX_2D:
14180389061SMatthew G. Knepley     for (d = 0; d < 2; ++d) {
14280389061SMatthew G. Knepley       if (point[d] < -1.0) {*inside = PETSC_FALSE; break;}
14380389061SMatthew G. Knepley       sum += point[d];
14480389061SMatthew G. Knepley     }
14580389061SMatthew G. Knepley     if (sum > 0.0) {*inside = PETSC_FALSE; break;}
14680389061SMatthew G. Knepley     break;
1476c0c04f5SMatthew G. Knepley   case REFINER_HEX_2D:
14880389061SMatthew G. Knepley     for (d = 0; d < 2; ++d) if ((point[d] < -1.0) || (point[d] > 1.0)) {*inside = PETSC_FALSE; break;}
14980389061SMatthew G. Knepley     break;
15080389061SMatthew G. Knepley   default:
15180389061SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
15280389061SMatthew G. Knepley   }
15380389061SMatthew G. Knepley   PetscFunctionReturn(0);
15480389061SMatthew G. Knepley }
15580389061SMatthew G. Knepley 
15686150812SJed Brown static PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[])
15775d3a19aSMatthew G. Knepley {
1586ce3c06aSMatthew G. Knepley   PetscInt       cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax;
15975d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
16075d3a19aSMatthew G. Knepley 
16175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
16275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
16375d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
16475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
16575d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
16675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
16775d3a19aSMatthew G. Knepley   switch (refiner) {
1689b1a0e7fSLawrence Mitchell   case REFINER_NOOP:
1693478d7aaSMatthew G. Knepley     break;
1700314a74cSLawrence Mitchell   case REFINER_SIMPLEX_1D:
1710314a74cSLawrence Mitchell     depthSize[0] = vEnd - vStart + cEnd - cStart;         /* Add a vertex on every cell. */
1720314a74cSLawrence Mitchell     depthSize[1] = 2*(cEnd - cStart);                     /* Split every cell in 2. */
1730314a74cSLawrence Mitchell     break;
1749b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
17575d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fEnd - fStart;         /* Add a vertex on every face */
17675d3a19aSMatthew G. Knepley     depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */
17775d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cEnd - cStart);                     /* Every cell split into 4 cells */
17875d3a19aSMatthew G. Knepley     break;
1799b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
18075d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
18175d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
18275d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fMax - fStart;                                         /* Add a vertex on every face, but not hybrid faces */
18375d3a19aSMatthew G. Knepley     depthSize[1] = 2*(fMax - fStart) + 3*(cMax - cStart) + (fEnd - fMax) + (cEnd - cMax); /* Every interior face is split into 2 faces, 3 faces are added for each interior cell, and one in each hybrid cell */
18475d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax);                                   /* Interior cells split into 4 cells, Hybrid cells split into 2 cells */
18575d3a19aSMatthew G. Knepley     break;
186*e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_2D:
187*e5337592SStefano Zampini     depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */
188*e5337592SStefano Zampini     depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart);         /* Every face is split into 2 faces and 3 faces are added for each cell */
189*e5337592SStefano Zampini     depthSize[2] = 3*(cEnd - cStart);                             /* Every cell split into 3 cells */
190*e5337592SStefano Zampini     break;
1919b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
192149f48fdSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */
19375d3a19aSMatthew 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 */
19475d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cEnd - cStart);                             /* Every cell split into 4 cells */
19575d3a19aSMatthew G. Knepley     break;
1969b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
197a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
198a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
199a97b51b8SMatthew G. Knepley     /* Quadrilateral */
200a97b51b8SMatthew G. Knepley     depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart;                 /* Add a vertex on every face and cell */
201a97b51b8SMatthew 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 */
202a97b51b8SMatthew G. Knepley     depthSize[2] = 4*(cMax - cStart);                                             /* Every cell split into 4 cells */
203a97b51b8SMatthew G. Knepley     /* Segment Prisms */
204a97b51b8SMatthew G. Knepley     depthSize[0] += 0;                                                            /* No hybrid vertices */
205a97b51b8SMatthew G. Knepley     depthSize[1] +=   (fEnd - fMax)  +   (cEnd - cMax);                           /* Every hybrid face remains and 1 faces is added for each hybrid cell */
206a97b51b8SMatthew G. Knepley     depthSize[2] += 2*(cEnd - cMax);                                              /* Every hybrid cell split into 2 cells */
207a97b51b8SMatthew G. Knepley     break;
2089b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
209b5da9499SMatthew G. Knepley     depthSize[0] =    vEnd - vStart  +    eEnd - eStart;                    /* Add a vertex on every edge */
210b5da9499SMatthew 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 */
211b5da9499SMatthew G. Knepley     depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart);                   /* Every face split into 4 faces and 8 faces are added for each cell */
212b5da9499SMatthew G. Knepley     depthSize[3] = 8*(cEnd - cStart);                                       /* Every cell split into 8 cells */
213b5da9499SMatthew G. Knepley     break;
2149b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
215b5da9499SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
2166ce3c06aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
217b5da9499SMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
218dae4404aSMatthew G. Knepley     /* Tetrahedra */
219dae4404aSMatthew G. Knepley     depthSize[0]  =    vEnd - vStart  +    eMax - eStart;                    /* Add a vertex on every interior edge */
220dae4404aSMatthew 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 */
221dae4404aSMatthew G. Knepley     depthSize[2]  = 4*(fMax - fStart) + 8*(cMax - cStart);                   /* Every interior face split into 4 faces, 8 faces added for each interior cell */
222dae4404aSMatthew G. Knepley     depthSize[3]  = 8*(cMax - cStart);                                       /* Every interior cell split into 8 cells */
223dae4404aSMatthew G. Knepley     /* Triangular Prisms */
224dae4404aSMatthew G. Knepley     depthSize[0] += 0;                                                       /* No hybrid vertices */
225dae4404aSMatthew G. Knepley     depthSize[1] +=   (eEnd - eMax)   +   (fEnd - fMax);                     /* Every hybrid edge remains, 1 edge for every hybrid face */
2266ce3c06aSMatthew 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 */
227dae4404aSMatthew G. Knepley     depthSize[3] += 4*(cEnd - cMax);                                         /* Every hybrid cell split into 4 cells */
228b5da9499SMatthew G. Knepley     break;
229*e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_3D:
230*e5337592SStefano Zampini     depthSize[0] = vEnd - vStart + fEnd - fStart + eEnd - eStart + cEnd - cStart; /* Add a vertex on every face, edge and cell */
231*e5337592SStefano Zampini     depthSize[1] = 2*(eEnd - eStart) + 3*(fEnd - fStart) + 4*(cEnd - cStart);     /* Every edge is split into 2 edges, 3 edges are added for each face, and 4 for each cell */
232*e5337592SStefano Zampini     depthSize[2] = 3*(fEnd - fStart) + 6*(cEnd - cStart);                         /* Every face is split into 3 faces and 6 faces are added for each cell */
233*e5337592SStefano Zampini     depthSize[3] = 4*(cEnd - cStart);                                             /* Every cell split into 4 cells */
234*e5337592SStefano Zampini     break;
2359b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
2366ce3c06aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */
2376ce3c06aSMatthew 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 */
2386ce3c06aSMatthew 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 */
2396ce3c06aSMatthew G. Knepley     depthSize[3] = 8*(cEnd - cStart);                                             /* Every cell split into 8 cells */
2406ce3c06aSMatthew G. Knepley     break;
2419b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
24227fcede3SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
24327fcede3SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
24427fcede3SMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
24527fcede3SMatthew G. Knepley     /* Hexahedra */
24627fcede3SMatthew G. Knepley     depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */
24727fcede3SMatthew 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 */
24827fcede3SMatthew 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 */
24927fcede3SMatthew G. Knepley     depthSize[3] = 8*(cMax - cStart);                                             /* Every cell split into 8 cells */
25027fcede3SMatthew G. Knepley     /* Quadrilateral Prisms */
25127fcede3SMatthew G. Knepley     depthSize[0] += 0;                                                            /* No hybrid vertices */
25227fcede3SMatthew G. Knepley     depthSize[1] +=   (eEnd - eMax)   +   (fEnd - fMax)   +   (cEnd - cMax);      /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */
25327fcede3SMatthew 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 */
25427fcede3SMatthew G. Knepley     depthSize[3] += 4*(cEnd - cMax);                                              /* Every hybrid cell split into 4 cells */
25527fcede3SMatthew G. Knepley     break;
25675d3a19aSMatthew G. Knepley   default:
25775d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
25875d3a19aSMatthew G. Knepley   }
25975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
26075d3a19aSMatthew G. Knepley }
26175d3a19aSMatthew G. Knepley 
26242525629SMatthew G. Knepley /* Return triangle edge for orientation o, if it is r for o == 0 */
26342525629SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) {
264518a8359SMatthew G. Knepley   return (o < 0 ? 2-(o+r) : o+r)%3;
265518a8359SMatthew G. Knepley }
266de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) {
267de65f515SMatthew G. Knepley   return (o < 0 ? 2-(o+s) : 3+s-o)%3;
268de65f515SMatthew G. Knepley }
269518a8359SMatthew G. Knepley 
270518a8359SMatthew G. Knepley /* Return triangle subface for orientation o, if it is r for o == 0 */
271518a8359SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) {
2724bae88c7SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%3;
27342525629SMatthew G. Knepley }
274de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) {
275de65f515SMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 3+s-o)%3;
276de65f515SMatthew G. Knepley }
27742525629SMatthew G. Knepley 
278*e5337592SStefano Zampini /* Return the interior edge number connecting the midpoints of the triangle edges r
279*e5337592SStefano Zampini    and r+1 in the transitive closure for triangle orientation o */
280*e5337592SStefano Zampini PETSC_STATIC_INLINE PetscInt GetTriMidEdge_Static(PetscInt o, PetscInt r) {
281431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+r) : o+r)%3;
282431647a4SMatthew G. Knepley }
283*e5337592SStefano Zampini PETSC_STATIC_INLINE PetscInt GetTriMidEdgeInverse_Static(PetscInt o, PetscInt s) {
284431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+s) : 3+s-o)%3;
285431647a4SMatthew G. Knepley }
286431647a4SMatthew G. Knepley 
287*e5337592SStefano Zampini /* Return the interior edge number connecting the midpoint of the triangle edge r
288*e5337592SStefano Zampini    (in the transitive closure) and the vertex in the interior of the face for triangle orientation o */
289*e5337592SStefano Zampini PETSC_STATIC_INLINE PetscInt GetTriInteriorEdge_Static(PetscInt o, PetscInt r) {
290*e5337592SStefano Zampini   return (o < 0 ? 2-(o+r) : o+r)%3;
291*e5337592SStefano Zampini }
292*e5337592SStefano Zampini PETSC_STATIC_INLINE PetscInt GetTriInteriorEdgeInverse_Static(PetscInt o, PetscInt s) {
293*e5337592SStefano Zampini   return (o < 0 ? 2-(o+s) : 3+s-o)%3;
294*e5337592SStefano Zampini }
29542525629SMatthew G. Knepley 
296e3f8b1d6SMatthew G. Knepley /* Return quad edge for orientation o, if it is r for o == 0 */
297e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) {
298e3f8b1d6SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%4;
299e3f8b1d6SMatthew G. Knepley }
300d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) {
301d6d937efSMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 4+s-o)%4;
302d6d937efSMatthew G. Knepley }
303e3f8b1d6SMatthew G. Knepley 
304e3f8b1d6SMatthew G. Knepley /* Return quad subface for orientation o, if it is r for o == 0 */
305e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) {
3064bae88c7SMatthew G. Knepley   return (o < 0 ? 4-(o+r) : o+r)%4;
30742525629SMatthew G. Knepley }
308d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) {
309d6d937efSMatthew G. Knepley   return (o < 0 ? 4-(o+s) : 4+s-o)%4;
310d6d937efSMatthew G. Knepley }
31142525629SMatthew G. Knepley 
31286150812SJed Brown static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
31375d3a19aSMatthew G. Knepley {
314b5da9499SMatthew 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;
31575d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
31675d3a19aSMatthew G. Knepley 
31775d3a19aSMatthew G. Knepley   PetscFunctionBegin;
3182a5d0125SJed Brown   if (!refiner) PetscFunctionReturn(0);
31975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
32075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
32175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
32275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
32375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
32475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
3252a5d0125SJed Brown   ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
32675d3a19aSMatthew G. Knepley   switch (refiner) {
3270314a74cSLawrence Mitchell   case REFINER_SIMPLEX_1D:
3280314a74cSLawrence Mitchell     /* All cells have 2 vertices */
3290314a74cSLawrence Mitchell     for (c = cStart; c < cEnd; ++c) {
3300314a74cSLawrence Mitchell       for (r = 0; r < 2; ++r) {
3310314a74cSLawrence Mitchell         const PetscInt newp = cStartNew + (c - cStart)*2 + r;
3320314a74cSLawrence Mitchell 
3330314a74cSLawrence Mitchell         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
3340314a74cSLawrence Mitchell       }
3350314a74cSLawrence Mitchell     }
3360314a74cSLawrence Mitchell     /* Old vertices have identical supports */
3370314a74cSLawrence Mitchell     for (v = vStart; v < vEnd; ++v) {
3380314a74cSLawrence Mitchell       const PetscInt newp = vStartNew + (v - vStart);
3390314a74cSLawrence Mitchell       PetscInt       size;
3400314a74cSLawrence Mitchell 
3410314a74cSLawrence Mitchell       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
3420314a74cSLawrence Mitchell       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
3430314a74cSLawrence Mitchell     }
3440314a74cSLawrence Mitchell     /* Cell vertices have support 2 */
3450314a74cSLawrence Mitchell     for (c = cStart; c < cEnd; ++c) {
3460314a74cSLawrence Mitchell       const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart);
3470314a74cSLawrence Mitchell 
3480314a74cSLawrence Mitchell       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
3490314a74cSLawrence Mitchell     }
3500314a74cSLawrence Mitchell     break;
3519b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
35275d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
35375d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
35475d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
35575d3a19aSMatthew G. Knepley         const PetscInt newp = (c - cStart)*4 + r;
35675d3a19aSMatthew G. Knepley 
35775d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
35875d3a19aSMatthew G. Knepley       }
35975d3a19aSMatthew G. Knepley     }
36075d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
36175d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
36275d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
36375d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
36475d3a19aSMatthew G. Knepley         PetscInt       size;
36575d3a19aSMatthew G. Knepley 
36675d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
36775d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
36875d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
36975d3a19aSMatthew G. Knepley       }
37075d3a19aSMatthew G. Knepley     }
37175d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
37275d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
37375d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
37475d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
37575d3a19aSMatthew G. Knepley 
37675d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
37775d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
37875d3a19aSMatthew G. Knepley       }
37975d3a19aSMatthew G. Knepley     }
38075d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
38175d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
38275d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
38375d3a19aSMatthew G. Knepley       PetscInt       size;
38475d3a19aSMatthew G. Knepley 
38575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
38675d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
38775d3a19aSMatthew G. Knepley     }
38875d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
38975d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
39075d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
39175d3a19aSMatthew G. Knepley       PetscInt       size;
39275d3a19aSMatthew G. Knepley 
39375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
39475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr);
39575d3a19aSMatthew G. Knepley     }
39675d3a19aSMatthew G. Knepley     break;
397*e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_2D:
398*e5337592SStefano Zampini     /* All cells have 4 faces */
399*e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
400*e5337592SStefano Zampini       for (r = 0; r < 3; ++r) {
401*e5337592SStefano Zampini         const PetscInt newp = (c - cStart)*3 + r;
402*e5337592SStefano Zampini 
403*e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
404*e5337592SStefano Zampini       }
405*e5337592SStefano Zampini     }
406*e5337592SStefano Zampini     /* Split faces have 2 vertices and the same cells as the parent */
407*e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
408*e5337592SStefano Zampini       for (r = 0; r < 2; ++r) {
409*e5337592SStefano Zampini         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
410*e5337592SStefano Zampini         PetscInt       size;
411*e5337592SStefano Zampini 
412*e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
413*e5337592SStefano Zampini         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
414*e5337592SStefano Zampini         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
415*e5337592SStefano Zampini       }
416*e5337592SStefano Zampini     }
417*e5337592SStefano Zampini     /* Interior faces have 2 vertices and 2 cells */
418*e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
419*e5337592SStefano Zampini       for (r = 0; r < 3; ++r) {
420*e5337592SStefano Zampini         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
421*e5337592SStefano Zampini 
422*e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
423*e5337592SStefano Zampini         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
424*e5337592SStefano Zampini       }
425*e5337592SStefano Zampini     }
426*e5337592SStefano Zampini     /* Old vertices have identical supports */
427*e5337592SStefano Zampini     for (v = vStart; v < vEnd; ++v) {
428*e5337592SStefano Zampini       const PetscInt newp = vStartNew + (v - vStart);
429*e5337592SStefano Zampini       PetscInt       size;
430*e5337592SStefano Zampini 
431*e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
432*e5337592SStefano Zampini       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
433*e5337592SStefano Zampini     }
434*e5337592SStefano Zampini     /* Split-face vertices have cells + 2 supports */
435*e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
436*e5337592SStefano Zampini       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
437*e5337592SStefano Zampini       PetscInt       size;
438*e5337592SStefano Zampini 
439*e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
440*e5337592SStefano Zampini       ierr = DMPlexSetSupportSize(rdm, newp, size + 2);CHKERRQ(ierr);
441*e5337592SStefano Zampini     }
442*e5337592SStefano Zampini     /* Interior vertices have 3 supports */
443*e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
444*e5337592SStefano Zampini       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
445*e5337592SStefano Zampini 
446*e5337592SStefano Zampini       ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr);
447*e5337592SStefano Zampini     }
448*e5337592SStefano Zampini     break;
4499b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
45075d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
45175d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
45275d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
453149f48fdSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
45475d3a19aSMatthew G. Knepley 
45575d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
45675d3a19aSMatthew G. Knepley       }
45775d3a19aSMatthew G. Knepley     }
45875d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
45975d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
46075d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
46175d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
46275d3a19aSMatthew G. Knepley         PetscInt       size;
46375d3a19aSMatthew G. Knepley 
46475d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
46575d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
46675d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
46775d3a19aSMatthew G. Knepley       }
46875d3a19aSMatthew G. Knepley     }
46975d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
47075d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
47175d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
47275d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
47375d3a19aSMatthew G. Knepley 
47475d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
47575d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
47675d3a19aSMatthew G. Knepley       }
47775d3a19aSMatthew G. Knepley     }
47875d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
47975d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
48075d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
48175d3a19aSMatthew G. Knepley       PetscInt       size;
48275d3a19aSMatthew G. Knepley 
48375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
48475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
48575d3a19aSMatthew G. Knepley     }
48675d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
48775d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
48875d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
48975d3a19aSMatthew G. Knepley       PetscInt       size;
49075d3a19aSMatthew G. Knepley 
49175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
49275d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
49375d3a19aSMatthew G. Knepley     }
49475d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
49575d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
49675d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
49775d3a19aSMatthew G. Knepley 
49875d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
49975d3a19aSMatthew G. Knepley     }
50075d3a19aSMatthew G. Knepley     break;
5019b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
50275d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
50375d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
50475d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
50575d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
50675d3a19aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
50775d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
50875d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
50975d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
51075d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
51175d3a19aSMatthew G. Knepley 
51275d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
51375d3a19aSMatthew G. Knepley       }
51475d3a19aSMatthew G. Knepley     }
51575d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
51675d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
51775d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
51875d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
51975d3a19aSMatthew G. Knepley 
52075d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
52175d3a19aSMatthew G. Knepley       }
52275d3a19aSMatthew G. Knepley     }
52375d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
52475d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
52575d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
52675d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
52775d3a19aSMatthew G. Knepley         PetscInt       size;
52875d3a19aSMatthew G. Knepley 
52975d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
53075d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
53175d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
53275d3a19aSMatthew G. Knepley       }
53375d3a19aSMatthew G. Knepley     }
53475d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
53575d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
53675d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
53775d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
53875d3a19aSMatthew G. Knepley 
53975d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
54075d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
54175d3a19aSMatthew G. Knepley       }
54275d3a19aSMatthew G. Knepley     }
54375d3a19aSMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
54475d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
54575d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
54675d3a19aSMatthew G. Knepley       PetscInt       size;
54775d3a19aSMatthew G. Knepley 
54875d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
54975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
55075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
55175d3a19aSMatthew G. Knepley     }
55275d3a19aSMatthew G. Knepley     /* Hybrid cell faces have 2 vertices and 2 cells */
55375d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
55475d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
55575d3a19aSMatthew G. Knepley 
55675d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
55775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
55875d3a19aSMatthew G. Knepley     }
55975d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
56075d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
56175d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
56275d3a19aSMatthew G. Knepley       PetscInt       size;
56375d3a19aSMatthew G. Knepley 
56475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
56575d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
56675d3a19aSMatthew G. Knepley     }
56775d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
56875d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
56975d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
57075d3a19aSMatthew G. Knepley       const PetscInt *support;
57175d3a19aSMatthew G. Knepley       PetscInt       size, newSize = 2, s;
57275d3a19aSMatthew G. Knepley 
57375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
57475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
57575d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
57675d3a19aSMatthew G. Knepley         if (support[s] >= cMax) newSize += 1;
57775d3a19aSMatthew G. Knepley         else newSize += 2;
57875d3a19aSMatthew G. Knepley       }
57975d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr);
58075d3a19aSMatthew G. Knepley     }
58175d3a19aSMatthew G. Knepley     break;
5829b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
583a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
584a97b51b8SMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
585a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
586a97b51b8SMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
587a97b51b8SMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
588a97b51b8SMatthew G. Knepley     /* Interior cells have 4 faces */
589a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
590a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
591a97b51b8SMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
592a97b51b8SMatthew G. Knepley 
593a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
594a97b51b8SMatthew G. Knepley       }
595a97b51b8SMatthew G. Knepley     }
596a97b51b8SMatthew G. Knepley     /* Hybrid cells have 4 faces */
597a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
598a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
599a97b51b8SMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
600a97b51b8SMatthew G. Knepley 
601a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
602a97b51b8SMatthew G. Knepley       }
603a97b51b8SMatthew G. Knepley     }
604a97b51b8SMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
605a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
606a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
607a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
608a97b51b8SMatthew G. Knepley         PetscInt       size;
609a97b51b8SMatthew G. Knepley 
610a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
611a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
612a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
613a97b51b8SMatthew G. Knepley       }
614a97b51b8SMatthew G. Knepley     }
615a97b51b8SMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
616a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
617a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
618a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
619a97b51b8SMatthew G. Knepley 
620a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
621a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
622a97b51b8SMatthew G. Knepley       }
623a97b51b8SMatthew G. Knepley     }
624a97b51b8SMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
625a97b51b8SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
626a97b51b8SMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
627a97b51b8SMatthew G. Knepley       PetscInt       size;
628a97b51b8SMatthew G. Knepley 
629a97b51b8SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
630a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
631a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
632a97b51b8SMatthew G. Knepley     }
633a97b51b8SMatthew G. Knepley     /* Hybrid cell faces have 2 vertices and 2 cells */
634a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
635a97b51b8SMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
636a97b51b8SMatthew G. Knepley 
637a97b51b8SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
638a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
639a97b51b8SMatthew G. Knepley     }
640a97b51b8SMatthew G. Knepley     /* Old vertices have identical supports */
641a97b51b8SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
642a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
643a97b51b8SMatthew G. Knepley       PetscInt       size;
644a97b51b8SMatthew G. Knepley 
645a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
646a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
647a97b51b8SMatthew G. Knepley     }
648a97b51b8SMatthew G. Knepley     /* Face vertices have 2 + cells supports */
649a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
650a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
651a97b51b8SMatthew G. Knepley       PetscInt       size;
652a97b51b8SMatthew G. Knepley 
653a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
654a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
655a97b51b8SMatthew G. Knepley     }
656a97b51b8SMatthew G. Knepley     /* Cell vertices have 4 supports */
657a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
658a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
659a97b51b8SMatthew G. Knepley 
660a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
661a97b51b8SMatthew G. Knepley     }
662a97b51b8SMatthew G. Knepley     break;
6639b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
664b5da9499SMatthew G. Knepley     /* All cells have 4 faces */
665b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
666b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
667dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
668b5da9499SMatthew G. Knepley 
669b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
670b5da9499SMatthew G. Knepley       }
671b5da9499SMatthew G. Knepley     }
672b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
673b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
674b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
675b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
676b5da9499SMatthew G. Knepley         PetscInt       size;
677b5da9499SMatthew G. Knepley 
678b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
679b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
680b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
681b5da9499SMatthew G. Knepley       }
682b5da9499SMatthew G. Knepley     }
6839ddff745SMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
684b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
685b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
686b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r;
687b5da9499SMatthew G. Knepley 
688b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
689b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
690b5da9499SMatthew G. Knepley       }
691b5da9499SMatthew G. Knepley     }
692b5da9499SMatthew G. Knepley     /* Split edges have 2 vertices and the same faces */
693b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
694b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
695b5da9499SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
696b5da9499SMatthew G. Knepley         PetscInt       size;
697b5da9499SMatthew G. Knepley 
698b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
699b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
700b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
701b5da9499SMatthew G. Knepley       }
702b5da9499SMatthew G. Knepley     }
703b5da9499SMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
704b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
705b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
706b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
707b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
708b5da9499SMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
709b5da9499SMatthew G. Knepley 
710b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
711b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
712b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
713b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
714b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
715b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
716b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
717b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
71886f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
719*e5337592SStefano Zampini           er = GetTriMidEdgeInverse_Static(ornt[c], r);
720b5da9499SMatthew G. Knepley           if (er == eint[c]) {
721b5da9499SMatthew G. Knepley             intFaces += 1;
722b5da9499SMatthew G. Knepley           } else {
723b5da9499SMatthew G. Knepley             intFaces += 2;
724b5da9499SMatthew G. Knepley           }
725b5da9499SMatthew G. Knepley         }
726b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
727b5da9499SMatthew G. Knepley       }
728b5da9499SMatthew G. Knepley     }
7299ddff745SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
730b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
731b5da9499SMatthew G. Knepley       const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
732b5da9499SMatthew G. Knepley 
733b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
734b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
735b5da9499SMatthew G. Knepley     }
736b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
737b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
738b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
739b5da9499SMatthew G. Knepley       PetscInt       size;
740b5da9499SMatthew G. Knepley 
741b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
742b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
743b5da9499SMatthew G. Knepley     }
744b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + faces*2 + cells*0/1 supports */
745b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
746b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
747b5da9499SMatthew G. Knepley       PetscInt       size, *star = NULL, starSize, s, cellSize = 0;
748b5da9499SMatthew G. Knepley 
749b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
750b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
751b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
752b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
753b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
754b5da9499SMatthew G. Knepley 
755b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
756b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
757b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
758b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
759b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
76042525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
761b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
762b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
763b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
76442525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
76542525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
766b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
767b5da9499SMatthew G. Knepley         }
768b5da9499SMatthew G. Knepley       }
769b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
770b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr);
771b5da9499SMatthew G. Knepley     }
772b5da9499SMatthew G. Knepley     break;
7739b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
7746ce3c06aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart),
7756ce3c06aSMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
776dae4404aSMatthew G. Knepley     /* Interior cells have 4 faces */
777dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
778dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
779dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
780dae4404aSMatthew G. Knepley 
781dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
782dae4404aSMatthew G. Knepley       }
783dae4404aSMatthew G. Knepley     }
784dae4404aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
785dae4404aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
786dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
787dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
788dae4404aSMatthew G. Knepley 
789dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr);
790dae4404aSMatthew G. Knepley       }
791dae4404aSMatthew G. Knepley     }
7926ce3c06aSMatthew G. Knepley     /* Interior split faces have 3 edges and the same cells as the parent */
793dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
794dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
795dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
796dae4404aSMatthew G. Knepley         PetscInt       size;
797dae4404aSMatthew G. Knepley 
798dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
799dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
800dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
801dae4404aSMatthew G. Knepley       }
802dae4404aSMatthew G. Knepley     }
803dae4404aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
804dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
805dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
806dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r;
807dae4404aSMatthew G. Knepley 
808dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
809dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
810dae4404aSMatthew G. Knepley       }
811dae4404aSMatthew G. Knepley     }
8126ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
8136ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
8146ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
8156ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
8166ce3c06aSMatthew G. Knepley         PetscInt       size;
8176ce3c06aSMatthew G. Knepley 
8186ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
8196ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
8206ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
8216ce3c06aSMatthew G. Knepley       }
8226ce3c06aSMatthew G. Knepley     }
8236ce3c06aSMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
8246ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
8256ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
8266ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r;
8276ce3c06aSMatthew G. Knepley 
8286ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
8296ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
8306ce3c06aSMatthew G. Knepley       }
8316ce3c06aSMatthew G. Knepley     }
8326ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces */
833dae4404aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
834dae4404aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
835dae4404aSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
836dae4404aSMatthew G. Knepley         PetscInt       size;
837dae4404aSMatthew G. Knepley 
838dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
839dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
840dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
841dae4404aSMatthew G. Knepley       }
842dae4404aSMatthew G. Knepley     }
8436ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
844dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
845dae4404aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
846dae4404aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
847dae4404aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
848dae4404aSMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
849dae4404aSMatthew G. Knepley 
850dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
851dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
852dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
853dae4404aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
854dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
855dae4404aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
856dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
857dae4404aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
8586ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
859dae4404aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
860*e5337592SStefano Zampini             er = GetTriMidEdgeInverse_Static(ornt[c], r);
861dae4404aSMatthew G. Knepley             if (er == eint[c]) {
862dae4404aSMatthew G. Knepley               intFaces += 1;
863dae4404aSMatthew G. Knepley             } else {
864dae4404aSMatthew G. Knepley               intFaces += 2;
865dae4404aSMatthew G. Knepley             }
8666ce3c06aSMatthew G. Knepley           } else {
8676ce3c06aSMatthew G. Knepley             intFaces += 1;
8686ce3c06aSMatthew G. Knepley           }
869dae4404aSMatthew G. Knepley         }
870dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
871dae4404aSMatthew G. Knepley       }
872dae4404aSMatthew G. Knepley     }
8736ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
874dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
875dae4404aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
876dae4404aSMatthew G. Knepley 
877dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
878dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
879dae4404aSMatthew G. Knepley     }
8806ce3c06aSMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
881dae4404aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
8826ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
8836ce3c06aSMatthew G. Knepley       PetscInt       size;
8846ce3c06aSMatthew G. Knepley 
8856ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
8866ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
8876ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
8886ce3c06aSMatthew G. Knepley     }
8896ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
8906ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
8916ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
892dae4404aSMatthew G. Knepley       PetscInt       size;
893dae4404aSMatthew G. Knepley 
894dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
895dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
8966ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr);
897dae4404aSMatthew G. Knepley     }
8986ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
899dae4404aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
900dae4404aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
901dae4404aSMatthew G. Knepley       PetscInt       size;
902dae4404aSMatthew G. Knepley 
903dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
904dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
905dae4404aSMatthew G. Knepley     }
9066ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
9076ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
9086ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
909dae4404aSMatthew G. Knepley       const PetscInt *support;
9106ce3c06aSMatthew G. Knepley       PetscInt        size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0;
911dae4404aSMatthew G. Knepley 
9126ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
9136ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
914dae4404aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
9156ce3c06aSMatthew G. Knepley         if (support[s] < fMax) faceSize += 2;
9166ce3c06aSMatthew G. Knepley         else                   faceSize += 1;
917dae4404aSMatthew G. Knepley       }
9186ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
9196ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
9206ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
9216ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
9226ce3c06aSMatthew G. Knepley 
9236ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
9246ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
9256ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
9266ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
9276ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
9286ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
9296ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
9306ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
9316ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
9326ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
9336ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
9346ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
9356ce3c06aSMatthew G. Knepley         }
9366ce3c06aSMatthew G. Knepley       }
9376ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
9386ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr);
939dae4404aSMatthew G. Knepley     }
940dae4404aSMatthew G. Knepley     break;
941*e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_3D:
942*e5337592SStefano Zampini     /* All cells have 6 faces */
943*e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
944*e5337592SStefano Zampini       for (r = 0; r < 4; ++r) {
945*e5337592SStefano Zampini         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
946*e5337592SStefano Zampini 
947*e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
948*e5337592SStefano Zampini       }
949*e5337592SStefano Zampini     }
950*e5337592SStefano Zampini     /* Split faces have 4 edges and the same cells as the parent */
951*e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
952*e5337592SStefano Zampini       for (r = 0; r < 3; ++r) {
953*e5337592SStefano Zampini         const PetscInt newp = fStartNew + (f - fStart)*3 + r;
954*e5337592SStefano Zampini         PetscInt       size;
955*e5337592SStefano Zampini 
956*e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
957*e5337592SStefano Zampini         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
958*e5337592SStefano Zampini         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
959*e5337592SStefano Zampini       }
960*e5337592SStefano Zampini     }
961*e5337592SStefano Zampini     /* Interior cell faces have 4 edges and 2 cells */
962*e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
963*e5337592SStefano Zampini       for (r = 0; r < 6; ++r) {
964*e5337592SStefano Zampini         const PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + r;
965*e5337592SStefano Zampini 
966*e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
967*e5337592SStefano Zampini         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
968*e5337592SStefano Zampini       }
969*e5337592SStefano Zampini     }
970*e5337592SStefano Zampini     /* Split edges have 2 vertices and the same faces */
971*e5337592SStefano Zampini     for (e = eStart; e < eEnd; ++e) {
972*e5337592SStefano Zampini       for (r = 0; r < 2; ++r) {
973*e5337592SStefano Zampini         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
974*e5337592SStefano Zampini         PetscInt       size;
975*e5337592SStefano Zampini 
976*e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
977*e5337592SStefano Zampini         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
978*e5337592SStefano Zampini         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
979*e5337592SStefano Zampini       }
980*e5337592SStefano Zampini     }
981*e5337592SStefano Zampini     /* Face edges have 2 vertices and 2 + cell faces supports */
982*e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
983*e5337592SStefano Zampini       for (r = 0; r < 3; ++r) {
984*e5337592SStefano Zampini         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
985*e5337592SStefano Zampini         PetscInt        size;
986*e5337592SStefano Zampini 
987*e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
988*e5337592SStefano Zampini         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
989*e5337592SStefano Zampini         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
990*e5337592SStefano Zampini       }
991*e5337592SStefano Zampini     }
992*e5337592SStefano Zampini     /* Interior cell edges have 2 vertices and 3 faces */
993*e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
994*e5337592SStefano Zampini       for (r = 0; r < 4; ++r) {
995*e5337592SStefano Zampini         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r;
996*e5337592SStefano Zampini 
997*e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
998*e5337592SStefano Zampini         ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr);
999*e5337592SStefano Zampini       }
1000*e5337592SStefano Zampini     }
1001*e5337592SStefano Zampini     /* Old vertices have identical supports */
1002*e5337592SStefano Zampini     for (v = vStart; v < vEnd; ++v) {
1003*e5337592SStefano Zampini       const PetscInt newp = vStartNew + (v - vStart);
1004*e5337592SStefano Zampini       PetscInt       size;
1005*e5337592SStefano Zampini 
1006*e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
1007*e5337592SStefano Zampini       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
1008*e5337592SStefano Zampini     }
1009*e5337592SStefano Zampini     /* Edge vertices have 2 + faces supports */
1010*e5337592SStefano Zampini     for (e = eStart; e < eEnd; ++e) {
1011*e5337592SStefano Zampini       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
1012*e5337592SStefano Zampini       PetscInt       size;
1013*e5337592SStefano Zampini 
1014*e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
1015*e5337592SStefano Zampini       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
1016*e5337592SStefano Zampini     }
1017*e5337592SStefano Zampini     /* Face vertices have 3 + cells supports */
1018*e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
1019*e5337592SStefano Zampini       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart;
1020*e5337592SStefano Zampini       PetscInt       size;
1021*e5337592SStefano Zampini 
1022*e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
1023*e5337592SStefano Zampini       ierr = DMPlexSetSupportSize(rdm, newp, 3 + size);CHKERRQ(ierr);
1024*e5337592SStefano Zampini     }
1025*e5337592SStefano Zampini     /* Interior cell vertices have 4 supports */
1026*e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
1027*e5337592SStefano Zampini       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + fEnd - fStart + c - cStart;
1028*e5337592SStefano Zampini 
1029*e5337592SStefano Zampini       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
1030*e5337592SStefano Zampini     }
1031*e5337592SStefano Zampini     break;
10329b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
10332eabf88fSMatthew G. Knepley     /* All cells have 6 faces */
10342eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
10352eabf88fSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
10362eabf88fSMatthew G. Knepley         const PetscInt newp = (c - cStart)*8 + r;
10372eabf88fSMatthew G. Knepley 
10382eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
10392eabf88fSMatthew G. Knepley       }
10402eabf88fSMatthew G. Knepley     }
10412eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
10422eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
10432eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
10442eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
10452eabf88fSMatthew G. Knepley         PetscInt       size;
10462eabf88fSMatthew G. Knepley 
10472eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
10482eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
10492eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
10502eabf88fSMatthew G. Knepley       }
10512eabf88fSMatthew G. Knepley     }
10522eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
10532eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
10542eabf88fSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
10552eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
10562eabf88fSMatthew G. Knepley 
10572eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
10582eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
10592eabf88fSMatthew G. Knepley       }
10602eabf88fSMatthew G. Knepley     }
10612eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
10622eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
10632eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
10642eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
10652eabf88fSMatthew G. Knepley         PetscInt       size;
10662eabf88fSMatthew G. Knepley 
10672eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
10682eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
10692eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
10702eabf88fSMatthew G. Knepley       }
10712eabf88fSMatthew G. Knepley     }
10722eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
10732eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
10742eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
10752eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
10762eabf88fSMatthew G. Knepley         PetscInt       size;
10772eabf88fSMatthew G. Knepley 
10782eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
10792eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
10802eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
10812eabf88fSMatthew G. Knepley       }
10822eabf88fSMatthew G. Knepley     }
10832eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
10842eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
10852eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
10862eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
10872eabf88fSMatthew G. Knepley 
10882eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
10892eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
10902eabf88fSMatthew G. Knepley       }
10912eabf88fSMatthew G. Knepley     }
10922eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
10932eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
10942eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
10952eabf88fSMatthew G. Knepley       PetscInt       size;
10962eabf88fSMatthew G. Knepley 
10972eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
10982eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
10992eabf88fSMatthew G. Knepley     }
11002eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
11012eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
11022eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
11032eabf88fSMatthew G. Knepley       PetscInt       size;
11042eabf88fSMatthew G. Knepley 
11052eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
11062eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
11072eabf88fSMatthew G. Knepley     }
11082eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
11092eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
11102eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
11112eabf88fSMatthew G. Knepley       PetscInt       size;
11122eabf88fSMatthew G. Knepley 
11132eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
11142eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
11152eabf88fSMatthew G. Knepley     }
11162eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
11172eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
11182eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
11192eabf88fSMatthew G. Knepley 
11202eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
11212eabf88fSMatthew G. Knepley     }
11222eabf88fSMatthew G. Knepley     break;
11239b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
112427fcede3SMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart),
112527fcede3SMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
112627fcede3SMatthew G. Knepley     /* Interior cells have 6 faces */
112727fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
112827fcede3SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
112927fcede3SMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
113027fcede3SMatthew G. Knepley 
113127fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
113227fcede3SMatthew G. Knepley       }
113327fcede3SMatthew G. Knepley     }
113427fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces */
113527fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
113627fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
113727fcede3SMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
113827fcede3SMatthew G. Knepley 
113927fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
114027fcede3SMatthew G. Knepley       }
114127fcede3SMatthew G. Knepley     }
114227fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
114327fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
114427fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
114527fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
114627fcede3SMatthew G. Knepley         PetscInt       size;
114727fcede3SMatthew G. Knepley 
114827fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
114927fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
115027fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
115127fcede3SMatthew G. Knepley       }
115227fcede3SMatthew G. Knepley     }
115327fcede3SMatthew G. Knepley     /* Interior cell faces have 4 edges and 2 cells */
115427fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
115527fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
115627fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
115727fcede3SMatthew G. Knepley 
115827fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
115927fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
116027fcede3SMatthew G. Knepley       }
116127fcede3SMatthew G. Knepley     }
116227fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
116327fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
116427fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
116527fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
116627fcede3SMatthew G. Knepley         PetscInt       size;
116727fcede3SMatthew G. Knepley 
116827fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
116927fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
117027fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
117127fcede3SMatthew G. Knepley       }
117227fcede3SMatthew G. Knepley     }
117327fcede3SMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
117427fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
117527fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
117627fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r;
117727fcede3SMatthew G. Knepley 
117827fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
117927fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
118027fcede3SMatthew G. Knepley       }
118127fcede3SMatthew G. Knepley     }
118227fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
118327fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
118427fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
118527fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
118627fcede3SMatthew G. Knepley         PetscInt       size;
118727fcede3SMatthew G. Knepley 
118827fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
118927fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
119027fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
119127fcede3SMatthew G. Knepley       }
119227fcede3SMatthew G. Knepley     }
119327fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
119427fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
119527fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
119627fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
119727fcede3SMatthew G. Knepley         PetscInt       size;
119827fcede3SMatthew G. Knepley 
119927fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
120027fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
120127fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
120227fcede3SMatthew G. Knepley       }
120327fcede3SMatthew G. Knepley     }
120427fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
120527fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
120627fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
120727fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
120827fcede3SMatthew G. Knepley 
120927fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
121027fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
121127fcede3SMatthew G. Knepley       }
121227fcede3SMatthew G. Knepley     }
121327fcede3SMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
121427fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
121527fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
121627fcede3SMatthew G. Knepley       PetscInt       size;
121727fcede3SMatthew G. Knepley 
121827fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
121927fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
122027fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
122127fcede3SMatthew G. Knepley     }
122227fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
122327fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
122427fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
122527fcede3SMatthew G. Knepley       PetscInt       size;
122627fcede3SMatthew G. Knepley 
122727fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
122827fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
122927fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
123027fcede3SMatthew G. Knepley     }
123127fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
123227fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
123327fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
123427fcede3SMatthew G. Knepley 
123527fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
123627fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
123727fcede3SMatthew G. Knepley     }
123827fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
123927fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
124027fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
124127fcede3SMatthew G. Knepley       PetscInt       size;
124227fcede3SMatthew G. Knepley 
124327fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
124427fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
124527fcede3SMatthew G. Knepley     }
124627fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
124727fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
124827fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
124927fcede3SMatthew G. Knepley       PetscInt       size;
125027fcede3SMatthew G. Knepley 
125127fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
125227fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
125327fcede3SMatthew G. Knepley     }
125427fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
125527fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
125627fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
125727fcede3SMatthew G. Knepley       PetscInt       size;
125827fcede3SMatthew G. Knepley 
125927fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
126027fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
126127fcede3SMatthew G. Knepley     }
126227fcede3SMatthew G. Knepley     /* Interior cell vertices have 6 supports */
126327fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
126427fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
126527fcede3SMatthew G. Knepley 
126627fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
126727fcede3SMatthew G. Knepley     }
126827fcede3SMatthew G. Knepley     break;
126975d3a19aSMatthew G. Knepley   default:
127075d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
127175d3a19aSMatthew G. Knepley   }
127275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
127375d3a19aSMatthew G. Knepley }
127475d3a19aSMatthew G. Knepley 
127586150812SJed Brown static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
127675d3a19aSMatthew G. Knepley {
1277b5da9499SMatthew G. Knepley   const PetscInt *faces, cellInd[4] = {0, 1, 2, 3};
12786ce3c06aSMatthew G. Knepley   PetscInt        cStart,    cEnd,    cMax,    vStart,    vEnd, vMax, fStart,    fEnd,    fMax,    eStart,    eEnd,    eMax;
12796ce3c06aSMatthew G. Knepley   PetscInt        cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew,    fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew;
12806ce3c06aSMatthew G. Knepley   PetscInt        depth, maxSupportSize, *supportRef, c, f, e, v, r, p;
128175d3a19aSMatthew G. Knepley   PetscErrorCode  ierr;
128275d3a19aSMatthew G. Knepley 
128375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
12842a5d0125SJed Brown   if (!refiner) PetscFunctionReturn(0);
128575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
128675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
128775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
128875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
128975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
129075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
129175d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
129275d3a19aSMatthew G. Knepley   ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr);
129375d3a19aSMatthew G. Knepley   switch (refiner) {
12940314a74cSLawrence Mitchell   case REFINER_SIMPLEX_1D:
12950314a74cSLawrence Mitchell     /* Max support size of refined mesh is 2 */
12960314a74cSLawrence Mitchell     ierr = PetscMalloc1(2, &supportRef);CHKERRQ(ierr);
12970314a74cSLawrence Mitchell     /* All cells have 2 vertices */
12980314a74cSLawrence Mitchell     for (c = cStart; c < cEnd; ++c) {
12990314a74cSLawrence Mitchell       const PetscInt  newv = vStartNew + (vEnd - vStart) + (c - cStart);
13000314a74cSLawrence Mitchell 
13010314a74cSLawrence Mitchell       for (r = 0; r < 2; ++r) {
13020314a74cSLawrence Mitchell         const PetscInt newp = cStartNew + (c - cStart)*2 + r;
13030314a74cSLawrence Mitchell         const PetscInt *cone;
13040314a74cSLawrence Mitchell         PetscInt        coneNew[2];
13050314a74cSLawrence Mitchell 
13060314a74cSLawrence Mitchell         ierr             = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
13070314a74cSLawrence Mitchell         coneNew[0]       = vStartNew + (cone[0] - vStart);
13080314a74cSLawrence Mitchell         coneNew[1]       = vStartNew + (cone[1] - vStart);
13090314a74cSLawrence Mitchell         coneNew[(r+1)%2] = newv;
13100314a74cSLawrence Mitchell         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
13110314a74cSLawrence Mitchell #if 1
13120314a74cSLawrence Mitchell         if ((newp < cStartNew) || (newp >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp, cStartNew, cEndNew);
13130314a74cSLawrence Mitchell         for (p = 0; p < 2; ++p) {
13140314a74cSLawrence 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);
13150314a74cSLawrence Mitchell         }
13160314a74cSLawrence Mitchell #endif
13170314a74cSLawrence Mitchell       }
13180314a74cSLawrence Mitchell     }
13190314a74cSLawrence Mitchell     /* Old vertices have identical supports */
13200314a74cSLawrence Mitchell     for (v = vStart; v < vEnd; ++v) {
13210314a74cSLawrence Mitchell       const PetscInt  newp = vStartNew + (v - vStart);
13220314a74cSLawrence Mitchell       const PetscInt *support, *cone;
13230314a74cSLawrence Mitchell       PetscInt        size, s;
13240314a74cSLawrence Mitchell 
13250314a74cSLawrence Mitchell       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
13260314a74cSLawrence Mitchell       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
13270314a74cSLawrence Mitchell       for (s = 0; s < size; ++s) {
13280314a74cSLawrence Mitchell         PetscInt r = 0;
13290314a74cSLawrence Mitchell 
13300314a74cSLawrence Mitchell         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
13310314a74cSLawrence Mitchell         if (cone[1] == v) r = 1;
13320314a74cSLawrence Mitchell         supportRef[s] = cStartNew + (support[s] - cStart)*2 + r;
13330314a74cSLawrence Mitchell       }
13340314a74cSLawrence Mitchell       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
13350314a74cSLawrence Mitchell #if 1
13360314a74cSLawrence Mitchell       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
13370314a74cSLawrence Mitchell       for (p = 0; p < size; ++p) {
13380314a74cSLawrence 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);
13390314a74cSLawrence Mitchell       }
13400314a74cSLawrence Mitchell #endif
13410314a74cSLawrence Mitchell     }
13420314a74cSLawrence Mitchell     /* Cell vertices have support of 2 cells */
13430314a74cSLawrence Mitchell     for (c = cStart; c < cEnd; ++c) {
13440314a74cSLawrence Mitchell       const PetscInt  newp = vStartNew + (vEnd - vStart) + (c - cStart);
13450314a74cSLawrence Mitchell 
13460314a74cSLawrence Mitchell       supportRef[0] = cStartNew + (c - cStart)*2 + 0;
13470314a74cSLawrence Mitchell       supportRef[1] = cStartNew + (c - cStart)*2 + 1;
13480314a74cSLawrence Mitchell       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
13490314a74cSLawrence Mitchell #if 1
13500314a74cSLawrence Mitchell       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
13510314a74cSLawrence Mitchell       for (p = 0; p < 2; ++p) {
13520314a74cSLawrence 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);
13530314a74cSLawrence Mitchell       }
13540314a74cSLawrence Mitchell #endif
13550314a74cSLawrence Mitchell     }
13560314a74cSLawrence Mitchell     ierr = PetscFree(supportRef);CHKERRQ(ierr);
13570314a74cSLawrence Mitchell     break;
13589b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
135975d3a19aSMatthew G. Knepley     /*
136075d3a19aSMatthew G. Knepley      2
136175d3a19aSMatthew G. Knepley      |\
136275d3a19aSMatthew G. Knepley      | \
136375d3a19aSMatthew G. Knepley      |  \
136475d3a19aSMatthew G. Knepley      |   \
136575d3a19aSMatthew G. Knepley      | C  \
136675d3a19aSMatthew G. Knepley      |     \
136775d3a19aSMatthew G. Knepley      |      \
136875d3a19aSMatthew G. Knepley      2---1---1
136975d3a19aSMatthew G. Knepley      |\  D  / \
137075d3a19aSMatthew G. Knepley      | 2   0   \
137175d3a19aSMatthew G. Knepley      |A \ /  B  \
137275d3a19aSMatthew G. Knepley      0---0-------1
137375d3a19aSMatthew G. Knepley      */
137475d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
137575d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
137675d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
137775d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
137875d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
137975d3a19aSMatthew G. Knepley 
138075d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
138175d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
138275d3a19aSMatthew G. Knepley       /* A triangle */
138375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
138475d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
138575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
138675d3a19aSMatthew G. Knepley       orntNew[1] = -2;
138775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
138875d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
138975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
139075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
139175d3a19aSMatthew G. Knepley #if 1
139275d3a19aSMatthew 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);
139375d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
139475d3a19aSMatthew 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);
139575d3a19aSMatthew G. Knepley       }
139675d3a19aSMatthew G. Knepley #endif
139775d3a19aSMatthew G. Knepley       /* B triangle */
139875d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
139975d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
140075d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
140175d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
140275d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
140375d3a19aSMatthew G. Knepley       orntNew[2] = -2;
140475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
140575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
140675d3a19aSMatthew G. Knepley #if 1
140775d3a19aSMatthew 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);
140875d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
140975d3a19aSMatthew 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);
141075d3a19aSMatthew G. Knepley       }
141175d3a19aSMatthew G. Knepley #endif
141275d3a19aSMatthew G. Knepley       /* C triangle */
141375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
141475d3a19aSMatthew G. Knepley       orntNew[0] = -2;
141575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
141675d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
141775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
141875d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
141975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
142075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
142175d3a19aSMatthew G. Knepley #if 1
142275d3a19aSMatthew 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);
142375d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
142475d3a19aSMatthew 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);
142575d3a19aSMatthew G. Knepley       }
142675d3a19aSMatthew G. Knepley #endif
142775d3a19aSMatthew G. Knepley       /* D triangle */
142875d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
142975d3a19aSMatthew G. Knepley       orntNew[0] = 0;
143075d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
143175d3a19aSMatthew G. Knepley       orntNew[1] = 0;
143275d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
143375d3a19aSMatthew G. Knepley       orntNew[2] = 0;
143475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
143575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
143675d3a19aSMatthew G. Knepley #if 1
143775d3a19aSMatthew 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);
143875d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
143975d3a19aSMatthew 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);
144075d3a19aSMatthew G. Knepley       }
144175d3a19aSMatthew G. Knepley #endif
144275d3a19aSMatthew G. Knepley     }
144375d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
144475d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1445854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
144675d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
144775d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
144875d3a19aSMatthew G. Knepley 
144975d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
145075d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1451297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
145275d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
145375d3a19aSMatthew G. Knepley 
145475d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
145575d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
145675d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
145775d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
145875d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
145975d3a19aSMatthew G. Knepley #if 1
146075d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
146175d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
146275d3a19aSMatthew 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);
146375d3a19aSMatthew G. Knepley         }
146475d3a19aSMatthew G. Knepley #endif
146575d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
146675d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
146775d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
146875d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
146975d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1470297d2bf4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
147175d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
147275d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
147375d3a19aSMatthew G. Knepley           }
1474297d2bf4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
147575d3a19aSMatthew G. Knepley         }
147675d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
147775d3a19aSMatthew G. Knepley #if 1
147875d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
147975d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
148075d3a19aSMatthew 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);
148175d3a19aSMatthew G. Knepley         }
148275d3a19aSMatthew G. Knepley #endif
148375d3a19aSMatthew G. Knepley       }
148475d3a19aSMatthew G. Knepley     }
148575d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
148675d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
148775d3a19aSMatthew G. Knepley       const PetscInt *cone;
148875d3a19aSMatthew G. Knepley 
148975d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
149075d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
149175d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
149275d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
149375d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
149475d3a19aSMatthew G. Knepley 
149575d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
149675d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
149775d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
149875d3a19aSMatthew G. Knepley #if 1
149975d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
150075d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
150175d3a19aSMatthew G. Knepley           if ((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);
150275d3a19aSMatthew G. Knepley         }
150375d3a19aSMatthew G. Knepley #endif
150475d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
150575d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
150675d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
150775d3a19aSMatthew G. Knepley #if 1
150875d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
150975d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
151075d3a19aSMatthew 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);
151175d3a19aSMatthew G. Knepley         }
151275d3a19aSMatthew G. Knepley #endif
151375d3a19aSMatthew G. Knepley       }
151475d3a19aSMatthew G. Knepley     }
151575d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
151675d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
151775d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
151875d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
151975d3a19aSMatthew G. Knepley       PetscInt        size, s;
152075d3a19aSMatthew G. Knepley 
152175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
152275d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
152375d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
152475d3a19aSMatthew G. Knepley         PetscInt r = 0;
152575d3a19aSMatthew G. Knepley 
152675d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
152775d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
152875d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
152975d3a19aSMatthew G. Knepley       }
153075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
153175d3a19aSMatthew G. Knepley #if 1
153275d3a19aSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
153375d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
153475d3a19aSMatthew G. Knepley         if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
153575d3a19aSMatthew G. Knepley       }
153675d3a19aSMatthew G. Knepley #endif
153775d3a19aSMatthew G. Knepley     }
153875d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
153975d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
154075d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
154175d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
154275d3a19aSMatthew G. Knepley       PetscInt        size, s;
154375d3a19aSMatthew G. Knepley 
154475d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
154575d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
154675d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
154775d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
154875d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
154975d3a19aSMatthew G. Knepley         PetscInt r = 0;
155075d3a19aSMatthew G. Knepley 
155175d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
155275d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
155375d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
155475d3a19aSMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
155575d3a19aSMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
155675d3a19aSMatthew G. Knepley       }
155775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
155875d3a19aSMatthew G. Knepley #if 1
155975d3a19aSMatthew 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);
156075d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
156175d3a19aSMatthew 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);
156275d3a19aSMatthew G. Knepley       }
156375d3a19aSMatthew G. Knepley #endif
156475d3a19aSMatthew G. Knepley     }
156575d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
156675d3a19aSMatthew G. Knepley     break;
1567*e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_2D:
1568*e5337592SStefano Zampini     /*
1569*e5337592SStefano Zampini      2
1570*e5337592SStefano Zampini      |\
1571*e5337592SStefano Zampini      | \
1572*e5337592SStefano Zampini      |  \
1573*e5337592SStefano Zampini      |   \
1574*e5337592SStefano Zampini      | C  \
1575*e5337592SStefano Zampini      |     \
1576*e5337592SStefano Zampini      2      1
1577*e5337592SStefano Zampini      |\    / \
1578*e5337592SStefano Zampini      | 2  1   \
1579*e5337592SStefano Zampini      |  \/     \
1580*e5337592SStefano Zampini      |   |      \
1581*e5337592SStefano Zampini      |A  |   B   \
1582*e5337592SStefano Zampini      |   0        \
1583*e5337592SStefano Zampini      |   |         \
1584*e5337592SStefano Zampini      0---0----------1
1585*e5337592SStefano Zampini      */
1586*e5337592SStefano Zampini     /* All cells have 4 faces */
1587*e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
1588*e5337592SStefano Zampini       const PetscInt  newp = cStartNew + (c - cStart)*3;
1589*e5337592SStefano Zampini       const PetscInt *cone, *ornt;
1590*e5337592SStefano Zampini       PetscInt        coneNew[4], orntNew[4];
1591*e5337592SStefano Zampini 
1592*e5337592SStefano Zampini       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1593*e5337592SStefano Zampini       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1594*e5337592SStefano Zampini       /* A quad */
1595*e5337592SStefano Zampini       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
1596*e5337592SStefano Zampini       orntNew[0] = ornt[0];
1597*e5337592SStefano Zampini       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
1598*e5337592SStefano Zampini       orntNew[1] = 0;
1599*e5337592SStefano Zampini       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
1600*e5337592SStefano Zampini       orntNew[2] = -2;
1601*e5337592SStefano Zampini       coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
1602*e5337592SStefano Zampini       orntNew[3] = ornt[2];
1603*e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
1604*e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
1605*e5337592SStefano Zampini #if 1
1606*e5337592SStefano Zampini       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);
1607*e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
1608*e5337592SStefano Zampini         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);
1609*e5337592SStefano Zampini       }
1610*e5337592SStefano Zampini #endif
1611*e5337592SStefano Zampini       /* B quad */
1612*e5337592SStefano Zampini       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
1613*e5337592SStefano Zampini       orntNew[0] = ornt[0];
1614*e5337592SStefano Zampini       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
1615*e5337592SStefano Zampini       orntNew[1] = ornt[1];
1616*e5337592SStefano Zampini       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
1617*e5337592SStefano Zampini       orntNew[2] = 0;
1618*e5337592SStefano Zampini       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
1619*e5337592SStefano Zampini       orntNew[3] = -2;
1620*e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
1621*e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
1622*e5337592SStefano Zampini #if 1
1623*e5337592SStefano Zampini       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);
1624*e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
1625*e5337592SStefano Zampini         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);
1626*e5337592SStefano Zampini       }
1627*e5337592SStefano Zampini #endif
1628*e5337592SStefano Zampini       /* C quad */
1629*e5337592SStefano Zampini       coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
1630*e5337592SStefano Zampini       orntNew[0] = ornt[1];
1631*e5337592SStefano Zampini       coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
1632*e5337592SStefano Zampini       orntNew[1] = ornt[2];
1633*e5337592SStefano Zampini       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
1634*e5337592SStefano Zampini       orntNew[2] = 0;
1635*e5337592SStefano Zampini       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
1636*e5337592SStefano Zampini       orntNew[3] = -2;
1637*e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
1638*e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
1639*e5337592SStefano Zampini #if 1
1640*e5337592SStefano Zampini       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);
1641*e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
1642*e5337592SStefano Zampini         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);
1643*e5337592SStefano Zampini       }
1644*e5337592SStefano Zampini #endif
1645*e5337592SStefano Zampini     }
1646*e5337592SStefano Zampini     /* Split faces have 2 vertices and the same cells as the parent */
1647*e5337592SStefano Zampini     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1648*e5337592SStefano Zampini     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
1649*e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
1650*e5337592SStefano Zampini       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
1651*e5337592SStefano Zampini 
1652*e5337592SStefano Zampini       for (r = 0; r < 2; ++r) {
1653*e5337592SStefano Zampini         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1654*e5337592SStefano Zampini         const PetscInt *cone, *ornt, *support;
1655*e5337592SStefano Zampini         PetscInt        coneNew[2], coneSize, c, supportSize, s;
1656*e5337592SStefano Zampini 
1657*e5337592SStefano Zampini         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
1658*e5337592SStefano Zampini         coneNew[0]       = vStartNew + (cone[0] - vStart);
1659*e5337592SStefano Zampini         coneNew[1]       = vStartNew + (cone[1] - vStart);
1660*e5337592SStefano Zampini         coneNew[(r+1)%2] = newv;
1661*e5337592SStefano Zampini         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1662*e5337592SStefano Zampini #if 1
1663*e5337592SStefano Zampini         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1664*e5337592SStefano Zampini         for (p = 0; p < 2; ++p) {
1665*e5337592SStefano Zampini           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);
1666*e5337592SStefano Zampini         }
1667*e5337592SStefano Zampini #endif
1668*e5337592SStefano Zampini         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
1669*e5337592SStefano Zampini         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
1670*e5337592SStefano Zampini         for (s = 0; s < supportSize; ++s) {
1671*e5337592SStefano Zampini           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
1672*e5337592SStefano Zampini           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1673*e5337592SStefano Zampini           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
1674*e5337592SStefano Zampini           for (c = 0; c < coneSize; ++c) {
1675*e5337592SStefano Zampini             if (cone[c] == f) break;
1676*e5337592SStefano Zampini           }
1677*e5337592SStefano Zampini           supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
1678*e5337592SStefano Zampini         }
1679*e5337592SStefano Zampini         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
1680*e5337592SStefano Zampini #if 1
1681*e5337592SStefano Zampini         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1682*e5337592SStefano Zampini         for (p = 0; p < supportSize; ++p) {
1683*e5337592SStefano Zampini           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);
1684*e5337592SStefano Zampini         }
1685*e5337592SStefano Zampini #endif
1686*e5337592SStefano Zampini       }
1687*e5337592SStefano Zampini     }
1688*e5337592SStefano Zampini     /* Interior faces have 2 vertices and 2 cells */
1689*e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
1690*e5337592SStefano Zampini       const PetscInt *cone;
1691*e5337592SStefano Zampini 
1692*e5337592SStefano Zampini       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1693*e5337592SStefano Zampini       for (r = 0; r < 3; ++r) {
1694*e5337592SStefano Zampini         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
1695*e5337592SStefano Zampini         PetscInt       coneNew[2];
1696*e5337592SStefano Zampini         PetscInt       supportNew[2];
1697*e5337592SStefano Zampini 
1698*e5337592SStefano Zampini         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
1699*e5337592SStefano Zampini         coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd    - fStart) + (c - cStart);
1700*e5337592SStefano Zampini         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1701*e5337592SStefano Zampini #if 1
1702*e5337592SStefano Zampini         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1703*e5337592SStefano Zampini         for (p = 0; p < 2; ++p) {
1704*e5337592SStefano Zampini           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);
1705*e5337592SStefano Zampini         }
1706*e5337592SStefano Zampini #endif
1707*e5337592SStefano Zampini         supportNew[0] = (c - cStart)*3 + r%3;
1708*e5337592SStefano Zampini         supportNew[1] = (c - cStart)*3 + (r+1)%3;
1709*e5337592SStefano Zampini         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1710*e5337592SStefano Zampini #if 1
1711*e5337592SStefano Zampini         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1712*e5337592SStefano Zampini         for (p = 0; p < 2; ++p) {
1713*e5337592SStefano Zampini           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);
1714*e5337592SStefano Zampini         }
1715*e5337592SStefano Zampini #endif
1716*e5337592SStefano Zampini       }
1717*e5337592SStefano Zampini     }
1718*e5337592SStefano Zampini     /* Old vertices have identical supports */
1719*e5337592SStefano Zampini     for (v = vStart; v < vEnd; ++v) {
1720*e5337592SStefano Zampini       const PetscInt  newp = vStartNew + (v - vStart);
1721*e5337592SStefano Zampini       const PetscInt *support, *cone;
1722*e5337592SStefano Zampini       PetscInt        size, s;
1723*e5337592SStefano Zampini 
1724*e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
1725*e5337592SStefano Zampini       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
1726*e5337592SStefano Zampini       for (s = 0; s < size; ++s) {
1727*e5337592SStefano Zampini         PetscInt r = 0;
1728*e5337592SStefano Zampini 
1729*e5337592SStefano Zampini         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1730*e5337592SStefano Zampini         if (cone[1] == v) r = 1;
1731*e5337592SStefano Zampini         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
1732*e5337592SStefano Zampini       }
1733*e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
1734*e5337592SStefano Zampini #if 1
1735*e5337592SStefano Zampini       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
1736*e5337592SStefano Zampini       for (p = 0; p < size; ++p) {
1737*e5337592SStefano Zampini         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);
1738*e5337592SStefano Zampini       }
1739*e5337592SStefano Zampini #endif
1740*e5337592SStefano Zampini     }
1741*e5337592SStefano Zampini     /* Split-face vertices have cells + 2 supports */
1742*e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
1743*e5337592SStefano Zampini       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
1744*e5337592SStefano Zampini       const PetscInt *cone, *support;
1745*e5337592SStefano Zampini       PetscInt        size, s;
1746*e5337592SStefano Zampini 
1747*e5337592SStefano Zampini       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
1748*e5337592SStefano Zampini       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
1749*e5337592SStefano Zampini       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
1750*e5337592SStefano Zampini       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
1751*e5337592SStefano Zampini       for (s = 0; s < size; ++s) {
1752*e5337592SStefano Zampini         PetscInt r = 0;
1753*e5337592SStefano Zampini 
1754*e5337592SStefano Zampini         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1755*e5337592SStefano Zampini         if      (cone[1] == f) r = 1;
1756*e5337592SStefano Zampini         else if (cone[2] == f) r = 2;
1757*e5337592SStefano Zampini         supportRef[2+s+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
1758*e5337592SStefano Zampini       }
1759*e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
1760*e5337592SStefano Zampini #if 1
1761*e5337592SStefano Zampini       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
1762*e5337592SStefano Zampini       for (p = 0; p < 2+size; ++p) {
1763*e5337592SStefano Zampini         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);
1764*e5337592SStefano Zampini       }
1765*e5337592SStefano Zampini #endif
1766*e5337592SStefano Zampini     }
1767*e5337592SStefano Zampini     /* Interior vertices vertices have 3 supports */
1768*e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
1769*e5337592SStefano Zampini       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
1770*e5337592SStefano Zampini 
1771*e5337592SStefano Zampini       supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
1772*e5337592SStefano Zampini       supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
1773*e5337592SStefano Zampini       supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
1774*e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
1775*e5337592SStefano Zampini     }
1776*e5337592SStefano Zampini     ierr = PetscFree(supportRef);CHKERRQ(ierr);
1777*e5337592SStefano Zampini     break;
17789b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
177975d3a19aSMatthew G. Knepley     /*
178075d3a19aSMatthew G. Knepley      3---------2---------2
178175d3a19aSMatthew G. Knepley      |         |         |
178275d3a19aSMatthew G. Knepley      |    D    2    C    |
178375d3a19aSMatthew G. Knepley      |         |         |
178475d3a19aSMatthew G. Knepley      3----3----0----1----1
178575d3a19aSMatthew G. Knepley      |         |         |
178675d3a19aSMatthew G. Knepley      |    A    0    B    |
178775d3a19aSMatthew G. Knepley      |         |         |
178875d3a19aSMatthew G. Knepley      0---------0---------1
178975d3a19aSMatthew G. Knepley      */
179075d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
179175d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
179275d3a19aSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*4;
179375d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
179475d3a19aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
179575d3a19aSMatthew G. Knepley 
179675d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
179775d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
179875d3a19aSMatthew G. Knepley       /* A quad */
179975d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
180075d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
180175d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
180275d3a19aSMatthew G. Knepley       orntNew[1] = 0;
180375d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
180475d3a19aSMatthew G. Knepley       orntNew[2] = -2;
180575d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
180675d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
180775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
180875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
180975d3a19aSMatthew G. Knepley #if 1
181075d3a19aSMatthew 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);
181175d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
181275d3a19aSMatthew 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);
181375d3a19aSMatthew G. Knepley       }
181475d3a19aSMatthew G. Knepley #endif
181575d3a19aSMatthew G. Knepley       /* B quad */
181675d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
181775d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
181875d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
181975d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
182075d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
182175d3a19aSMatthew G. Knepley       orntNew[2] = 0;
182275d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
182375d3a19aSMatthew G. Knepley       orntNew[3] = -2;
182475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
182575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
182675d3a19aSMatthew G. Knepley #if 1
182775d3a19aSMatthew 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);
182875d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
182975d3a19aSMatthew 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);
183075d3a19aSMatthew G. Knepley       }
183175d3a19aSMatthew G. Knepley #endif
183275d3a19aSMatthew G. Knepley       /* C quad */
183375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
183475d3a19aSMatthew G. Knepley       orntNew[0] = -2;
183575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
183675d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
183775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
183875d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
183975d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
184075d3a19aSMatthew G. Knepley       orntNew[3] = 0;
184175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
184275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
184375d3a19aSMatthew G. Knepley #if 1
184475d3a19aSMatthew 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);
184575d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
184675d3a19aSMatthew 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);
184775d3a19aSMatthew G. Knepley       }
184875d3a19aSMatthew G. Knepley #endif
184975d3a19aSMatthew G. Knepley       /* D quad */
185075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
185175d3a19aSMatthew G. Knepley       orntNew[0] = 0;
185275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
185375d3a19aSMatthew G. Knepley       orntNew[1] = -2;
185475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
185575d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
185675d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
185775d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
185875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
185975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
186075d3a19aSMatthew G. Knepley #if 1
186175d3a19aSMatthew 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);
186275d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
186375d3a19aSMatthew 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);
186475d3a19aSMatthew G. Knepley       }
186575d3a19aSMatthew G. Knepley #endif
186675d3a19aSMatthew G. Knepley     }
186775d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
186875d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1869854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
187075d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
187175d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
187275d3a19aSMatthew G. Knepley 
187375d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
187475d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1875455d6cd4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
187675d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
187775d3a19aSMatthew G. Knepley 
187875d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
187975d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
188075d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
188175d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
188275d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
188375d3a19aSMatthew G. Knepley #if 1
188475d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
188575d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
188675d3a19aSMatthew 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);
188775d3a19aSMatthew G. Knepley         }
188875d3a19aSMatthew G. Knepley #endif
188975d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
189075d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
189175d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
189275d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
189375d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1894455d6cd4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
189575d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
189675d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
189775d3a19aSMatthew G. Knepley           }
1898455d6cd4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
189975d3a19aSMatthew G. Knepley         }
190075d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
190175d3a19aSMatthew G. Knepley #if 1
190275d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
190375d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
190475d3a19aSMatthew 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);
190575d3a19aSMatthew G. Knepley         }
190675d3a19aSMatthew G. Knepley #endif
190775d3a19aSMatthew G. Knepley       }
190875d3a19aSMatthew G. Knepley     }
190975d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
191075d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
191175d3a19aSMatthew G. Knepley       const PetscInt *cone;
191275d3a19aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
191375d3a19aSMatthew G. Knepley 
191475d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
191575d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
191675d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
191775d3a19aSMatthew G. Knepley 
191875d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
191975d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd    - fStart) + (c - cStart);
192075d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
192175d3a19aSMatthew G. Knepley #if 1
192275d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
192375d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
192475d3a19aSMatthew 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);
192575d3a19aSMatthew G. Knepley         }
192675d3a19aSMatthew G. Knepley #endif
192775d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
192875d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
192975d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
193075d3a19aSMatthew G. Knepley #if 1
193175d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
193275d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
193375d3a19aSMatthew 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);
193475d3a19aSMatthew G. Knepley         }
193575d3a19aSMatthew G. Knepley #endif
193675d3a19aSMatthew G. Knepley       }
193775d3a19aSMatthew G. Knepley     }
193875d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
193975d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
194075d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
194175d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
194275d3a19aSMatthew G. Knepley       PetscInt        size, s;
194375d3a19aSMatthew G. Knepley 
194475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
194575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
194675d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
194775d3a19aSMatthew G. Knepley         PetscInt r = 0;
194875d3a19aSMatthew G. Knepley 
194975d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
195075d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
195175d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
195275d3a19aSMatthew G. Knepley       }
195375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
195475d3a19aSMatthew G. Knepley #if 1
195575d3a19aSMatthew 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);
195675d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
195775d3a19aSMatthew 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);
195875d3a19aSMatthew G. Knepley       }
195975d3a19aSMatthew G. Knepley #endif
196075d3a19aSMatthew G. Knepley     }
196175d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
196275d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
196375d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
196475d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
196575d3a19aSMatthew G. Knepley       PetscInt        size, s;
196675d3a19aSMatthew G. Knepley 
196775d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
196875d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
196975d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
197075d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
197175d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
197275d3a19aSMatthew G. Knepley         PetscInt r = 0;
197375d3a19aSMatthew G. Knepley 
197475d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
197575d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
197675d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
197775d3a19aSMatthew G. Knepley         else if (cone[3] == f) r = 3;
197875d3a19aSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r;
197975d3a19aSMatthew G. Knepley       }
198075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
198175d3a19aSMatthew G. Knepley #if 1
198275d3a19aSMatthew 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);
198375d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
198475d3a19aSMatthew 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);
198575d3a19aSMatthew G. Knepley       }
198675d3a19aSMatthew G. Knepley #endif
198775d3a19aSMatthew G. Knepley     }
198875d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
198975d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
199075d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
199175d3a19aSMatthew G. Knepley       PetscInt       supportNew[4];
199275d3a19aSMatthew G. Knepley 
199375d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
199475d3a19aSMatthew G. Knepley         supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
199575d3a19aSMatthew G. Knepley       }
199675d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
199775d3a19aSMatthew G. Knepley     }
1998da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
199975d3a19aSMatthew G. Knepley     break;
20009b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
200175d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
200275d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
200375d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
200475d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
2005149f48fdSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr);
200675d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
200775d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
200875d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
200975d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
201075d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
201175d3a19aSMatthew G. Knepley 
201275d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
201375d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
201475d3a19aSMatthew G. Knepley       /* A triangle */
201575d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
201675d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
201775d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
201875d3a19aSMatthew G. Knepley       orntNew[1] = -2;
201975d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
202075d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
202175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
202275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
202375d3a19aSMatthew G. Knepley #if 1
2024149f48fdSMatthew 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);
202575d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2026149f48fdSMatthew 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);
202775d3a19aSMatthew G. Knepley       }
202875d3a19aSMatthew G. Knepley #endif
202975d3a19aSMatthew G. Knepley       /* B triangle */
203075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
203175d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
203275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
203375d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
203475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
203575d3a19aSMatthew G. Knepley       orntNew[2] = -2;
203675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
203775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
203875d3a19aSMatthew G. Knepley #if 1
2039a97b51b8SMatthew 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);
204075d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2041a97b51b8SMatthew 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);
204275d3a19aSMatthew G. Knepley       }
204375d3a19aSMatthew G. Knepley #endif
204475d3a19aSMatthew G. Knepley       /* C triangle */
204575d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
204675d3a19aSMatthew G. Knepley       orntNew[0] = -2;
204775d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
204875d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
204975d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
205075d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
205175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
205275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
205375d3a19aSMatthew G. Knepley #if 1
2054a97b51b8SMatthew 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);
205575d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2056a97b51b8SMatthew 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);
205775d3a19aSMatthew G. Knepley       }
205875d3a19aSMatthew G. Knepley #endif
205975d3a19aSMatthew G. Knepley       /* D triangle */
206075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
206175d3a19aSMatthew G. Knepley       orntNew[0] = 0;
206275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
206375d3a19aSMatthew G. Knepley       orntNew[1] = 0;
206475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
206575d3a19aSMatthew G. Knepley       orntNew[2] = 0;
206675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
206775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
206875d3a19aSMatthew G. Knepley #if 1
2069a97b51b8SMatthew 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);
207075d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2071a97b51b8SMatthew 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);
207275d3a19aSMatthew G. Knepley       }
207375d3a19aSMatthew G. Knepley #endif
207475d3a19aSMatthew G. Knepley     }
207575d3a19aSMatthew G. Knepley     /*
207675d3a19aSMatthew G. Knepley      2----3----3
207775d3a19aSMatthew G. Knepley      |         |
207875d3a19aSMatthew G. Knepley      |    B    |
207975d3a19aSMatthew G. Knepley      |         |
208075d3a19aSMatthew G. Knepley      0----4--- 1
208175d3a19aSMatthew G. Knepley      |         |
208275d3a19aSMatthew G. Knepley      |    A    |
208375d3a19aSMatthew G. Knepley      |         |
208475d3a19aSMatthew G. Knepley      0----2----1
208575d3a19aSMatthew G. Knepley      */
208675d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
208775d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
208875d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
208975d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
2090ea00e70eSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4], r;
209175d3a19aSMatthew G. Knepley 
209275d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
209375d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2094ea00e70eSMatthew G. Knepley       r    = (ornt[0] < 0 ? 1 : 0);
209575d3a19aSMatthew G. Knepley       /* A quad */
2096ea00e70eSMatthew G. Knepley       coneNew[0]   = fStartNew + (cone[0] - fStart)*2 + r;
209775d3a19aSMatthew G. Knepley       orntNew[0]   = ornt[0];
2098ea00e70eSMatthew G. Knepley       coneNew[1]   = fStartNew + (cone[1] - fStart)*2 + r;
209975d3a19aSMatthew G. Knepley       orntNew[1]   = ornt[1];
2100ea00e70eSMatthew G. Knepley       coneNew[2+r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax);
2101ea00e70eSMatthew G. Knepley       orntNew[2+r] = 0;
2102ea00e70eSMatthew G. Knepley       coneNew[3-r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
2103ea00e70eSMatthew G. Knepley       orntNew[3-r] = 0;
210475d3a19aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
210575d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
210675d3a19aSMatthew G. Knepley #if 1
210775d3a19aSMatthew 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);
210875d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
210975d3a19aSMatthew 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);
211075d3a19aSMatthew G. Knepley       }
211175d3a19aSMatthew G. Knepley #endif
211275d3a19aSMatthew G. Knepley       /* B quad */
2113ea00e70eSMatthew G. Knepley       coneNew[0]   = fStartNew + (cone[0] - fStart)*2 + 1-r;
211475d3a19aSMatthew G. Knepley       orntNew[0]   = ornt[0];
2115ea00e70eSMatthew G. Knepley       coneNew[1]   = fStartNew + (cone[1] - fStart)*2 + 1-r;
211675d3a19aSMatthew G. Knepley       orntNew[1]   = ornt[1];
2117ea00e70eSMatthew G. Knepley       coneNew[2+r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
2118ea00e70eSMatthew G. Knepley       orntNew[2+r] = 0;
2119ea00e70eSMatthew G. Knepley       coneNew[3-r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax);
2120ea00e70eSMatthew G. Knepley       orntNew[3-r] = 0;
212175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
212275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
212375d3a19aSMatthew G. Knepley #if 1
212475d3a19aSMatthew 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);
212575d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
212675d3a19aSMatthew 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);
212775d3a19aSMatthew G. Knepley       }
212875d3a19aSMatthew G. Knepley #endif
212975d3a19aSMatthew G. Knepley     }
213075d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
213175d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2132854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
213375d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
213475d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
213575d3a19aSMatthew G. Knepley 
213675d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
213775d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
2138297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
213975d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
214075d3a19aSMatthew G. Knepley 
214175d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
214275d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
214375d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
214475d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
214575d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
214675d3a19aSMatthew G. Knepley #if 1
214775d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
214875d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
214975d3a19aSMatthew 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);
215075d3a19aSMatthew G. Knepley         }
215175d3a19aSMatthew G. Knepley #endif
215275d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
215375d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
215475d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
215575d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
215675d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2157297d2bf4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2158ea00e70eSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == f) break;
2159ea00e70eSMatthew G. Knepley           if (support[s] >= cMax) {
2160ea00e70eSMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r);
2161ea00e70eSMatthew G. Knepley           } else {
2162297d2bf4SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
216375d3a19aSMatthew G. Knepley           }
216475d3a19aSMatthew G. Knepley         }
216575d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
216675d3a19aSMatthew G. Knepley #if 1
216775d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
216875d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
216975d3a19aSMatthew 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);
217075d3a19aSMatthew G. Knepley         }
217175d3a19aSMatthew G. Knepley #endif
217275d3a19aSMatthew G. Knepley       }
217375d3a19aSMatthew G. Knepley     }
217475d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
217575d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
217675d3a19aSMatthew G. Knepley       const PetscInt *cone;
217775d3a19aSMatthew G. Knepley 
217875d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
217975d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
218075d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
218175d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
218275d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
218375d3a19aSMatthew G. Knepley 
218475d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
218575d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
218675d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
218775d3a19aSMatthew G. Knepley #if 1
218875d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
218975d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
219075d3a19aSMatthew 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);
219175d3a19aSMatthew G. Knepley         }
219275d3a19aSMatthew G. Knepley #endif
219375d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
219475d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
219575d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
219675d3a19aSMatthew G. Knepley #if 1
219775d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
219875d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
219975d3a19aSMatthew 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);
220075d3a19aSMatthew G. Knepley         }
220175d3a19aSMatthew G. Knepley #endif
220275d3a19aSMatthew G. Knepley       }
220375d3a19aSMatthew G. Knepley     }
220475d3a19aSMatthew G. Knepley     /* Interior hybrid faces have 2 vertices and the same cells */
220575d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
220675d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
2207ea00e70eSMatthew G. Knepley       const PetscInt *cone, *ornt;
220875d3a19aSMatthew G. Knepley       const PetscInt *support;
220975d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
221075d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
221175d3a19aSMatthew G. Knepley       PetscInt        size, s, r;
221275d3a19aSMatthew G. Knepley 
221375d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
221475d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
221575d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
221675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
221775d3a19aSMatthew G. Knepley #if 1
221875d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
221975d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
222075d3a19aSMatthew 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);
222175d3a19aSMatthew G. Knepley       }
222275d3a19aSMatthew G. Knepley #endif
222375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
222475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
222575d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
222675d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2227ea00e70eSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
222875d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r) {
222975d3a19aSMatthew G. Knepley           if (cone[r+2] == f) break;
223075d3a19aSMatthew G. Knepley         }
2231ea00e70eSMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r);
223275d3a19aSMatthew G. Knepley       }
223375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
223475d3a19aSMatthew G. Knepley #if 1
223575d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
223675d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
223775d3a19aSMatthew 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);
223875d3a19aSMatthew G. Knepley       }
223975d3a19aSMatthew G. Knepley #endif
224075d3a19aSMatthew G. Knepley     }
224175d3a19aSMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
224275d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
224375d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
224475d3a19aSMatthew G. Knepley       const PetscInt *cone;
224575d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
224675d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
224775d3a19aSMatthew G. Knepley 
224875d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
224975d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
225075d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
225175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
225275d3a19aSMatthew G. Knepley #if 1
225375d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
225475d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
225575d3a19aSMatthew 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);
225675d3a19aSMatthew G. Knepley       }
225775d3a19aSMatthew G. Knepley #endif
225875d3a19aSMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
225975d3a19aSMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
226075d3a19aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
226175d3a19aSMatthew G. Knepley #if 1
226275d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
226375d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
226475d3a19aSMatthew 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);
226575d3a19aSMatthew G. Knepley       }
226675d3a19aSMatthew G. Knepley #endif
226775d3a19aSMatthew G. Knepley     }
226875d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
226975d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
227075d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
227175d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
227275d3a19aSMatthew G. Knepley       PetscInt        size, s;
227375d3a19aSMatthew G. Knepley 
227475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
227575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
227675d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
227775d3a19aSMatthew G. Knepley         if (support[s] >= fMax) {
227875d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax);
227975d3a19aSMatthew G. Knepley         } else {
228075d3a19aSMatthew G. Knepley           PetscInt r = 0;
228175d3a19aSMatthew G. Knepley 
228275d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
228375d3a19aSMatthew G. Knepley           if (cone[1] == v) r = 1;
228475d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
228575d3a19aSMatthew G. Knepley         }
228675d3a19aSMatthew G. Knepley       }
228775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
228875d3a19aSMatthew G. Knepley #if 1
228975d3a19aSMatthew 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);
229075d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
229175d3a19aSMatthew 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);
229275d3a19aSMatthew G. Knepley       }
229375d3a19aSMatthew G. Knepley #endif
229475d3a19aSMatthew G. Knepley     }
229575d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
229675d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
229775d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
229875d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
229975d3a19aSMatthew G. Knepley       PetscInt        size, newSize = 2, s;
230075d3a19aSMatthew G. Knepley 
230175d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
230275d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
230375d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
230475d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
230575d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
230675d3a19aSMatthew G. Knepley         PetscInt r = 0;
230775d3a19aSMatthew G. Knepley 
230875d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
230975d3a19aSMatthew G. Knepley         if (support[s] >= cMax) {
231075d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax);
231175d3a19aSMatthew G. Knepley 
231275d3a19aSMatthew G. Knepley           newSize += 1;
231375d3a19aSMatthew G. Knepley         } else {
231475d3a19aSMatthew G. Knepley           if      (cone[1] == f) r = 1;
231575d3a19aSMatthew G. Knepley           else if (cone[2] == f) r = 2;
231675d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
231775d3a19aSMatthew G. Knepley           supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r;
231875d3a19aSMatthew G. Knepley 
231975d3a19aSMatthew G. Knepley           newSize += 2;
232075d3a19aSMatthew G. Knepley         }
232175d3a19aSMatthew G. Knepley       }
232275d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
232375d3a19aSMatthew G. Knepley #if 1
232475d3a19aSMatthew 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);
232575d3a19aSMatthew G. Knepley       for (p = 0; p < newSize; ++p) {
232675d3a19aSMatthew 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);
232775d3a19aSMatthew G. Knepley       }
232875d3a19aSMatthew G. Knepley #endif
232975d3a19aSMatthew G. Knepley     }
233075d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
233175d3a19aSMatthew G. Knepley     break;
23329b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
2333a97b51b8SMatthew G. Knepley     /* Hybrid Hex 2D */
2334a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
2335a97b51b8SMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
2336a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
2337a97b51b8SMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
2338a97b51b8SMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr);
2339a97b51b8SMatthew G. Knepley     /* Interior cells have 4 faces */
2340a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
2341a97b51b8SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
2342a97b51b8SMatthew G. Knepley       const PetscInt *cone, *ornt;
2343a97b51b8SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
2344a97b51b8SMatthew G. Knepley 
2345a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2346a97b51b8SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2347a97b51b8SMatthew G. Knepley       /* A quad */
2348a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2349a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2350a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 0;
2351a97b51b8SMatthew G. Knepley       orntNew[1] = 0;
2352a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 3;
2353a97b51b8SMatthew G. Knepley       orntNew[2] = -2;
2354a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
2355a97b51b8SMatthew G. Knepley       orntNew[3] = ornt[3];
2356a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2357a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2358a97b51b8SMatthew G. Knepley #if 1
2359a97b51b8SMatthew 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);
2360a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2361a97b51b8SMatthew 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);
2362a97b51b8SMatthew G. Knepley       }
2363a97b51b8SMatthew G. Knepley #endif
2364a97b51b8SMatthew G. Knepley       /* B quad */
2365a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2366a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2367a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2368a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2369a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 1;
2370a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
2371a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 0;
2372a97b51b8SMatthew G. Knepley       orntNew[3] = -2;
2373a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2374a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2375a97b51b8SMatthew G. Knepley #if 1
2376a97b51b8SMatthew 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);
2377a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2378a97b51b8SMatthew 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);
2379a97b51b8SMatthew G. Knepley       }
2380a97b51b8SMatthew G. Knepley #endif
2381a97b51b8SMatthew G. Knepley       /* C quad */
2382a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 1;
2383a97b51b8SMatthew G. Knepley       orntNew[0] = -2;
2384a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2385a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2386a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
2387a97b51b8SMatthew G. Knepley       orntNew[2] = ornt[2];
2388a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 2;
2389a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
2390a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2391a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2392a97b51b8SMatthew G. Knepley #if 1
2393a97b51b8SMatthew 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);
2394a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2395a97b51b8SMatthew 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);
2396a97b51b8SMatthew G. Knepley       }
2397a97b51b8SMatthew G. Knepley #endif
2398a97b51b8SMatthew G. Knepley       /* D quad */
2399a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 3;
2400a97b51b8SMatthew G. Knepley       orntNew[0] = 0;
2401a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 2;
2402a97b51b8SMatthew G. Knepley       orntNew[1] = -2;
2403a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
2404a97b51b8SMatthew G. Knepley       orntNew[2] = ornt[2];
2405a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
2406a97b51b8SMatthew G. Knepley       orntNew[3] = ornt[3];
2407a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2408a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2409a97b51b8SMatthew G. Knepley #if 1
2410a97b51b8SMatthew 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);
2411a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2412a97b51b8SMatthew 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);
2413a97b51b8SMatthew G. Knepley       }
2414a97b51b8SMatthew G. Knepley #endif
2415a97b51b8SMatthew G. Knepley     }
2416a97b51b8SMatthew G. Knepley     /*
2417a97b51b8SMatthew G. Knepley      2----3----3
2418a97b51b8SMatthew G. Knepley      |         |
2419a97b51b8SMatthew G. Knepley      |    B    |
2420a97b51b8SMatthew G. Knepley      |         |
2421a97b51b8SMatthew G. Knepley      0----4--- 1
2422a97b51b8SMatthew G. Knepley      |         |
2423a97b51b8SMatthew G. Knepley      |    A    |
2424a97b51b8SMatthew G. Knepley      |         |
2425a97b51b8SMatthew G. Knepley      0----2----1
2426a97b51b8SMatthew G. Knepley      */
2427a97b51b8SMatthew G. Knepley     /* Hybrid cells have 4 faces */
2428a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
2429a97b51b8SMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
2430a97b51b8SMatthew G. Knepley       const PetscInt *cone, *ornt;
2431a97b51b8SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
2432a97b51b8SMatthew G. Knepley 
2433a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2434a97b51b8SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2435a97b51b8SMatthew G. Knepley       /* A quad */
2436a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2437a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2438a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2439a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2440a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax);
2441a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
2442a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (fEnd    - fMax) + (c - cMax);
2443a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
2444a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2445a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2446a97b51b8SMatthew G. Knepley #if 1
2447a97b51b8SMatthew 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);
2448a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2449a97b51b8SMatthew 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);
2450a97b51b8SMatthew G. Knepley       }
2451a97b51b8SMatthew G. Knepley #endif
2452a97b51b8SMatthew G. Knepley       /* B quad */
2453a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2454a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2455a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2456a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2457a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (fEnd    - fMax) + (c - cMax);
2458a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
2459a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax);
2460a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
2461a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2462a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2463a97b51b8SMatthew G. Knepley #if 1
2464a97b51b8SMatthew 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);
2465a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2466a97b51b8SMatthew 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);
2467a97b51b8SMatthew G. Knepley       }
2468a97b51b8SMatthew G. Knepley #endif
2469a97b51b8SMatthew G. Knepley     }
2470a97b51b8SMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
2471a97b51b8SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2472854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
2473a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
2474a97b51b8SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
2475a97b51b8SMatthew G. Knepley 
2476a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
2477a97b51b8SMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
2478a97b51b8SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
2479a97b51b8SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
2480a97b51b8SMatthew G. Knepley 
2481a97b51b8SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2482a97b51b8SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
2483a97b51b8SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
2484a97b51b8SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
2485a97b51b8SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2486a97b51b8SMatthew G. Knepley #if 1
2487a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2488a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2489a97b51b8SMatthew 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);
2490a97b51b8SMatthew G. Knepley         }
2491a97b51b8SMatthew G. Knepley #endif
2492a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2493a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2494a97b51b8SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2495a97b51b8SMatthew G. Knepley           if (support[s] >= cMax) {
2496a97b51b8SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
2497a97b51b8SMatthew G. Knepley           } else {
2498a97b51b8SMatthew G. Knepley             ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2499a97b51b8SMatthew G. Knepley             ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2500a97b51b8SMatthew G. Knepley             ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2501a97b51b8SMatthew G. Knepley             for (c = 0; c < coneSize; ++c) {
2502a97b51b8SMatthew G. Knepley               if (cone[c] == f) break;
2503a97b51b8SMatthew G. Knepley             }
2504a97b51b8SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
2505a97b51b8SMatthew G. Knepley           }
2506a97b51b8SMatthew G. Knepley         }
2507a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2508a97b51b8SMatthew G. Knepley #if 1
2509a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2510a97b51b8SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2511a97b51b8SMatthew 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);
2512a97b51b8SMatthew G. Knepley         }
2513a97b51b8SMatthew G. Knepley #endif
2514a97b51b8SMatthew G. Knepley       }
2515a97b51b8SMatthew G. Knepley     }
2516a97b51b8SMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
2517a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
2518a97b51b8SMatthew G. Knepley       const PetscInt *cone;
2519a97b51b8SMatthew G. Knepley 
2520a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2521a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2522a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
2523a97b51b8SMatthew G. Knepley         PetscInt       coneNew[2], supportNew[2];
2524a97b51b8SMatthew G. Knepley 
2525a97b51b8SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2526a97b51b8SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fMax    - fStart) + (c - cStart);
2527a97b51b8SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2528a97b51b8SMatthew G. Knepley #if 1
2529a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2530a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2531a97b51b8SMatthew 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);
2532a97b51b8SMatthew G. Knepley         }
2533a97b51b8SMatthew G. Knepley #endif
2534a97b51b8SMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
2535a97b51b8SMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
2536a97b51b8SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2537a97b51b8SMatthew G. Knepley #if 1
2538a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2539a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2540a97b51b8SMatthew 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);
2541a97b51b8SMatthew G. Knepley         }
2542a97b51b8SMatthew G. Knepley #endif
2543a97b51b8SMatthew G. Knepley       }
2544a97b51b8SMatthew G. Knepley     }
2545a97b51b8SMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
2546a97b51b8SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
2547a97b51b8SMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
2548a97b51b8SMatthew G. Knepley       const PetscInt *cone, *support;
2549a97b51b8SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
2550a97b51b8SMatthew G. Knepley       PetscInt        size, s, r;
2551a97b51b8SMatthew G. Knepley 
2552a97b51b8SMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2553a97b51b8SMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
2554a97b51b8SMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
2555a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2556a97b51b8SMatthew G. Knepley #if 1
2557a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2558a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2559a97b51b8SMatthew 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);
2560a97b51b8SMatthew G. Knepley       }
2561a97b51b8SMatthew G. Knepley #endif
2562a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
2563a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2564a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2565a97b51b8SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2566a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r) {
2567a97b51b8SMatthew G. Knepley           if (cone[r+2] == f) break;
2568a97b51b8SMatthew G. Knepley         }
2569a97b51b8SMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
2570a97b51b8SMatthew G. Knepley       }
2571a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2572a97b51b8SMatthew G. Knepley #if 1
2573a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2574a97b51b8SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2575a97b51b8SMatthew 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);
2576a97b51b8SMatthew G. Knepley       }
2577a97b51b8SMatthew G. Knepley #endif
2578a97b51b8SMatthew G. Knepley     }
2579a97b51b8SMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
2580a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
2581a97b51b8SMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
2582a97b51b8SMatthew G. Knepley       const PetscInt *cone;
2583a97b51b8SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
2584a97b51b8SMatthew G. Knepley 
2585a97b51b8SMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2586a97b51b8SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
2587a97b51b8SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
2588a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2589a97b51b8SMatthew G. Knepley #if 1
2590a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2591a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2592a97b51b8SMatthew 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);
2593a97b51b8SMatthew G. Knepley       }
2594a97b51b8SMatthew G. Knepley #endif
2595a97b51b8SMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
2596a97b51b8SMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
2597a97b51b8SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2598a97b51b8SMatthew G. Knepley #if 1
2599a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2600a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2601a97b51b8SMatthew 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);
2602a97b51b8SMatthew G. Knepley       }
2603a97b51b8SMatthew G. Knepley #endif
2604a97b51b8SMatthew G. Knepley     }
2605a97b51b8SMatthew G. Knepley     /* Old vertices have identical supports */
2606a97b51b8SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
2607a97b51b8SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
2608a97b51b8SMatthew G. Knepley       const PetscInt *support, *cone;
2609a97b51b8SMatthew G. Knepley       PetscInt        size, s;
2610a97b51b8SMatthew G. Knepley 
2611a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
2612a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
2613a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2614a97b51b8SMatthew G. Knepley         if (support[s] >= fMax) {
2615a97b51b8SMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax);
2616a97b51b8SMatthew G. Knepley         } else {
2617a97b51b8SMatthew G. Knepley           PetscInt r = 0;
2618a97b51b8SMatthew G. Knepley 
2619a97b51b8SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2620a97b51b8SMatthew G. Knepley           if (cone[1] == v) r = 1;
2621a97b51b8SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
2622a97b51b8SMatthew G. Knepley         }
2623a97b51b8SMatthew G. Knepley       }
2624a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2625a97b51b8SMatthew G. Knepley #if 1
2626a97b51b8SMatthew 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);
2627a97b51b8SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2628a97b51b8SMatthew 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);
2629a97b51b8SMatthew G. Knepley       }
2630a97b51b8SMatthew G. Knepley #endif
2631a97b51b8SMatthew G. Knepley     }
2632a97b51b8SMatthew G. Knepley     /* Face vertices have 2 + cells supports */
2633a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
2634a97b51b8SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
2635a97b51b8SMatthew G. Knepley       const PetscInt *cone, *support;
2636a97b51b8SMatthew G. Knepley       PetscInt        size, s;
2637a97b51b8SMatthew G. Knepley 
2638a97b51b8SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
2639a97b51b8SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2640a97b51b8SMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
2641a97b51b8SMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
2642a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2643a97b51b8SMatthew G. Knepley         PetscInt r = 0;
2644a97b51b8SMatthew G. Knepley 
2645a97b51b8SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2646a97b51b8SMatthew G. Knepley         if (support[s] >= cMax) {
2647a97b51b8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax);
2648a97b51b8SMatthew G. Knepley         } else {
2649a97b51b8SMatthew G. Knepley           if      (cone[1] == f) r = 1;
2650a97b51b8SMatthew G. Knepley           else if (cone[2] == f) r = 2;
2651a97b51b8SMatthew G. Knepley           else if (cone[3] == f) r = 3;
2652a97b51b8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r;
2653a97b51b8SMatthew G. Knepley         }
2654a97b51b8SMatthew G. Knepley       }
2655a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2656a97b51b8SMatthew G. Knepley #if 1
2657a97b51b8SMatthew 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);
2658a97b51b8SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
2659a97b51b8SMatthew 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);
2660a97b51b8SMatthew G. Knepley       }
2661a97b51b8SMatthew G. Knepley #endif
2662a97b51b8SMatthew G. Knepley     }
2663a97b51b8SMatthew G. Knepley     /* Cell vertices have 4 supports */
2664a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
2665a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
2666a97b51b8SMatthew G. Knepley       PetscInt       supportNew[4];
2667a97b51b8SMatthew G. Knepley 
2668a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2669a97b51b8SMatthew G. Knepley         supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
2670a97b51b8SMatthew G. Knepley       }
2671a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2672a97b51b8SMatthew G. Knepley     }
2673a97b51b8SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
2674a97b51b8SMatthew G. Knepley     break;
26759b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
2676b5da9499SMatthew G. Knepley     /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
2677b5da9499SMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
2678b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2679b5da9499SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
2680b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
2681b5da9499SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
2682b5da9499SMatthew G. Knepley 
2683b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2684b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2685b5da9499SMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
2686518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
2687b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2688518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
2689b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2690518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
2691b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2692b5da9499SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
2693b5da9499SMatthew G. Knepley       orntNew[3] = 0;
2694b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2695b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2696b5da9499SMatthew G. Knepley #if 1
2697b5da9499SMatthew 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);
2698b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2699b5da9499SMatthew 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);
2700b5da9499SMatthew G. Knepley       }
2701b5da9499SMatthew G. Knepley #endif
2702b5da9499SMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
2703518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
2704b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2705518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
2706b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2707b5da9499SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
2708b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2709518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
2710b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2711b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2712b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2713b5da9499SMatthew G. Knepley #if 1
2714b5da9499SMatthew 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);
2715b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2716b5da9499SMatthew 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);
2717b5da9499SMatthew G. Knepley       }
2718b5da9499SMatthew G. Knepley #endif
2719b5da9499SMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
2720518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
2721b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2722b5da9499SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
2723b5da9499SMatthew G. Knepley       orntNew[1] = 0;
2724518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
2725b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2726518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
2727b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2728b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2729b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2730b5da9499SMatthew G. Knepley #if 1
2731b5da9499SMatthew 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);
2732b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2733b5da9499SMatthew 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);
2734b5da9499SMatthew G. Knepley       }
2735b5da9499SMatthew G. Knepley #endif
2736b5da9499SMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
2737b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
2738b5da9499SMatthew G. Knepley       orntNew[0] = 0;
2739518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
2740b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2741518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
2742b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2743518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
2744b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2745b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2746b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2747b5da9499SMatthew G. Knepley #if 1
2748b5da9499SMatthew 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);
2749b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2750b5da9499SMatthew 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);
2751b5da9499SMatthew G. Knepley       }
2752b5da9499SMatthew G. Knepley #endif
27533fe31fa2SToby Isaac       /* A' tetrahedron: {c, d, a, f} */
2754b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
2755b5da9499SMatthew G. Knepley       orntNew[0] = -3;
2756fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
2757*e5337592SStefano Zampini       orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0);
2758fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
2759fac4ab25SMatthew G. Knepley       orntNew[2] = 0;
2760fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
2761fac4ab25SMatthew G. Knepley       orntNew[3] = 2;
2762b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
2763b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
2764b5da9499SMatthew G. Knepley #if 1
2765b5da9499SMatthew 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);
2766b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2767b5da9499SMatthew 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);
2768b5da9499SMatthew G. Knepley       }
2769b5da9499SMatthew G. Knepley #endif
2770b5da9499SMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
2771b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
27723fe31fa2SToby Isaac       orntNew[0] = -2;
27733fe31fa2SToby Isaac       coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3;
2774*e5337592SStefano Zampini       orntNew[1] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 1)+1) : GetTriMidEdge_Static(ornt[3], 1);
27753fe31fa2SToby Isaac       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
2776b5da9499SMatthew G. Knepley       orntNew[2] = 0;
27773fe31fa2SToby Isaac       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
27783fe31fa2SToby Isaac       orntNew[3] = 0;
2779b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
2780b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
2781b5da9499SMatthew G. Knepley #if 1
2782b5da9499SMatthew 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);
2783b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2784b5da9499SMatthew 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);
2785b5da9499SMatthew G. Knepley       }
2786b5da9499SMatthew G. Knepley #endif
27873fe31fa2SToby Isaac       /* C' tetrahedron: {f, a, c, b} */
27883fe31fa2SToby Isaac       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
27893fe31fa2SToby Isaac       orntNew[0] = -2;
27903fe31fa2SToby Isaac       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
27913fe31fa2SToby Isaac       orntNew[1] = -2;
27923fe31fa2SToby Isaac       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
27933fe31fa2SToby Isaac       orntNew[2] = -1;
27943fe31fa2SToby Isaac       coneNew[3] = fStartNew + (cone[0] - fStart)*4 + 3;
2795*e5337592SStefano Zampini       orntNew[3] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2);
2796b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
2797b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
2798b5da9499SMatthew G. Knepley #if 1
2799b5da9499SMatthew 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);
2800b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2801b5da9499SMatthew 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);
2802b5da9499SMatthew G. Knepley       }
2803b5da9499SMatthew G. Knepley #endif
28043fe31fa2SToby Isaac       /* D' tetrahedron: {f, a, e, d} */
28053fe31fa2SToby Isaac       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
28063fe31fa2SToby Isaac       orntNew[0] = -2;
2807fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
28083fe31fa2SToby Isaac       orntNew[1] = -1;
28093fe31fa2SToby Isaac       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
28103fe31fa2SToby Isaac       orntNew[2] = -2;
28113fe31fa2SToby Isaac       coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3;
2812*e5337592SStefano Zampini       orntNew[3] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 1)+1) : GetTriMidEdge_Static(ornt[1], 1);
2813b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
2814b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
2815b5da9499SMatthew G. Knepley #if 1
2816b5da9499SMatthew 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);
2817b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2818b5da9499SMatthew 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);
2819b5da9499SMatthew G. Knepley       }
2820b5da9499SMatthew G. Knepley #endif
2821b5da9499SMatthew G. Knepley     }
2822b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
2823b5da9499SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2824854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
2825b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
2826b5da9499SMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
2827b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
2828b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
2829b5da9499SMatthew G. Knepley 
2830b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2831b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
2832b5da9499SMatthew G. Knepley       /* A triangle */
2833b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
2834b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2835b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
2836b5da9499SMatthew G. Knepley       orntNew[1] = -2;
2837b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
2838b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2839b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2840b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2841b5da9499SMatthew G. Knepley #if 1
2842b5da9499SMatthew 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);
2843b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2844b5da9499SMatthew 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);
2845b5da9499SMatthew G. Knepley       }
2846b5da9499SMatthew G. Knepley #endif
2847b5da9499SMatthew G. Knepley       /* B triangle */
2848b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
2849b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2850b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
2851b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2852b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
2853b5da9499SMatthew G. Knepley       orntNew[2] = -2;
2854b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2855b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2856b5da9499SMatthew G. Knepley #if 1
2857b5da9499SMatthew 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);
2858b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2859b5da9499SMatthew 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);
2860b5da9499SMatthew G. Knepley       }
2861b5da9499SMatthew G. Knepley #endif
2862b5da9499SMatthew G. Knepley       /* C triangle */
2863b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
2864b5da9499SMatthew G. Knepley       orntNew[0] = -2;
2865b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
2866b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2867b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
2868b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2869b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2870b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2871b5da9499SMatthew G. Knepley #if 1
2872b5da9499SMatthew 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);
2873b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2874b5da9499SMatthew 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);
2875b5da9499SMatthew G. Knepley       }
2876b5da9499SMatthew G. Knepley #endif
2877b5da9499SMatthew G. Knepley       /* D triangle */
2878b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
2879b5da9499SMatthew G. Knepley       orntNew[0] = 0;
2880b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
2881b5da9499SMatthew G. Knepley       orntNew[1] = 0;
2882b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
2883b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2884b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2885b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2886b5da9499SMatthew G. Knepley #if 1
2887b5da9499SMatthew 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);
2888b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2889b5da9499SMatthew 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);
2890b5da9499SMatthew G. Knepley       }
2891b5da9499SMatthew G. Knepley #endif
2892b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2893b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2894b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2895b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2896219f7b90SMatthew G. Knepley           PetscInt subf;
2897b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2898b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2899b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2900b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
2901b5da9499SMatthew G. Knepley             if (cone[c] == f) break;
2902b5da9499SMatthew G. Knepley           }
2903219f7b90SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
2904219f7b90SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
2905b5da9499SMatthew G. Knepley         }
2906b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
2907b5da9499SMatthew G. Knepley #if 1
29089ddff745SMatthew 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);
2909b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2910b5da9499SMatthew 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);
2911b5da9499SMatthew G. Knepley         }
2912b5da9499SMatthew G. Knepley #endif
2913b5da9499SMatthew G. Knepley       }
2914b5da9499SMatthew G. Knepley     }
2915b5da9499SMatthew G. Knepley     /* Interior faces have 3 edges and 2 cells */
2916b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2917b5da9499SMatthew G. Knepley       PetscInt        newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8;
2918b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
2919b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
2920b5da9499SMatthew G. Knepley       PetscInt        supportNew[2];
2921b5da9499SMatthew G. Knepley 
2922b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2923b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2924b5da9499SMatthew G. Knepley       /* Face A: {c, a, d} */
2925*e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
2926b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
2927*e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
2928b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
2929*e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2);
2930b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
2931b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2932b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2933b5da9499SMatthew G. Knepley #if 1
2934b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2935b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2936b5da9499SMatthew 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);
2937b5da9499SMatthew G. Knepley       }
2938b5da9499SMatthew G. Knepley #endif
2939b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
2940b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
2941b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2942b5da9499SMatthew G. Knepley #if 1
2943b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2944b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2945b5da9499SMatthew 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);
2946b5da9499SMatthew G. Knepley       }
2947b5da9499SMatthew G. Knepley #endif
2948b5da9499SMatthew G. Knepley       ++newp;
2949b5da9499SMatthew G. Knepley       /* Face B: {a, b, e} */
2950*e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
2951b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
2952*e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0);
2953b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
2954*e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
2955b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
2956b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2957b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2958b5da9499SMatthew G. Knepley #if 1
29594bb260e2SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2960b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2961b5da9499SMatthew 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);
2962b5da9499SMatthew G. Knepley       }
2963b5da9499SMatthew G. Knepley #endif
2964b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
2965b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
2966b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2967b5da9499SMatthew G. Knepley #if 1
2968b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2969b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2970b5da9499SMatthew 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);
2971b5da9499SMatthew G. Knepley       }
2972b5da9499SMatthew G. Knepley #endif
2973b5da9499SMatthew G. Knepley       ++newp;
2974b5da9499SMatthew G. Knepley       /* Face C: {c, f, b} */
2975*e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
2976b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
2977*e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
2978b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
2979*e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1);
2980b5da9499SMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
2981b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2982b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2983b5da9499SMatthew G. Knepley #if 1
2984b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2985b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2986b5da9499SMatthew 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);
2987b5da9499SMatthew G. Knepley       }
2988b5da9499SMatthew G. Knepley #endif
2989b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
2990b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2991b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2992b5da9499SMatthew G. Knepley #if 1
2993b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2994b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2995b5da9499SMatthew 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);
2996b5da9499SMatthew G. Knepley       }
2997b5da9499SMatthew G. Knepley #endif
2998b5da9499SMatthew G. Knepley       ++newp;
2999b5da9499SMatthew G. Knepley       /* Face D: {d, e, f} */
3000*e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0);
3001b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
3002*e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
3003b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
3004*e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
3005b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
3006b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3007b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3008b5da9499SMatthew G. Knepley #if 1
3009b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3010b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
3011b5da9499SMatthew 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);
3012b5da9499SMatthew G. Knepley       }
3013b5da9499SMatthew G. Knepley #endif
3014b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
3015b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
3016b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3017b5da9499SMatthew G. Knepley #if 1
3018b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3019b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3020b5da9499SMatthew 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);
3021b5da9499SMatthew G. Knepley       }
3022b5da9499SMatthew G. Knepley #endif
3023b5da9499SMatthew G. Knepley       ++newp;
3024b5da9499SMatthew G. Knepley       /* Face E: {d, f, a} */
3025*e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
3026b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
3027b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
30284bb260e2SMatthew G. Knepley       orntNew[1] = -2;
3029*e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
3030b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
3031b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3032b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3033b5da9499SMatthew G. Knepley #if 1
3034b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3035b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
3036b5da9499SMatthew 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);
3037b5da9499SMatthew G. Knepley       }
3038b5da9499SMatthew G. Knepley #endif
3039b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
3040b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
3041b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3042b5da9499SMatthew G. Knepley #if 1
3043b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3044b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3045b5da9499SMatthew 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);
3046b5da9499SMatthew G. Knepley       }
3047b5da9499SMatthew G. Knepley #endif
3048b5da9499SMatthew G. Knepley       ++newp;
3049b5da9499SMatthew G. Knepley       /* Face F: {c, a, f} */
3050*e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
3051b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
3052b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
30534bb260e2SMatthew G. Knepley       orntNew[1] = 0;
3054*e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
30552baf2947SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
3056b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3057b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3058b5da9499SMatthew G. Knepley #if 1
3059b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3060b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
3061b5da9499SMatthew 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);
3062b5da9499SMatthew G. Knepley       }
3063b5da9499SMatthew G. Knepley #endif
3064b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
3065b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
3066b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3067b5da9499SMatthew G. Knepley #if 1
3068b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3069b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3070b5da9499SMatthew 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);
3071b5da9499SMatthew G. Knepley       }
3072b5da9499SMatthew G. Knepley #endif
3073b5da9499SMatthew G. Knepley       ++newp;
3074b5da9499SMatthew G. Knepley       /* Face G: {e, a, f} */
3075*e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
3076b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
3077b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
3078fac4ab25SMatthew G. Knepley       orntNew[1] = 0;
3079*e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
3080b5da9499SMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
3081b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3082b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3083b5da9499SMatthew G. Knepley #if 1
3084b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3085b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
3086b5da9499SMatthew 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);
3087b5da9499SMatthew G. Knepley       }
3088b5da9499SMatthew G. Knepley #endif
3089b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
3090b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
3091b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3092b5da9499SMatthew G. Knepley #if 1
3093b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3094b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3095b5da9499SMatthew 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);
3096b5da9499SMatthew G. Knepley       }
3097b5da9499SMatthew G. Knepley #endif
3098b5da9499SMatthew G. Knepley       ++newp;
3099b5da9499SMatthew G. Knepley       /* Face H: {a, b, f} */
3100*e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
3101b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
3102*e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
3103b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
3104b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
31054bb260e2SMatthew G. Knepley       orntNew[2] = -2;
3106b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3107b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3108b5da9499SMatthew G. Knepley #if 1
3109b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3110b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
3111b5da9499SMatthew 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);
3112b5da9499SMatthew G. Knepley       }
3113b5da9499SMatthew G. Knepley #endif
3114b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
3115b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
3116b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3117b5da9499SMatthew G. Knepley #if 1
3118b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3119b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3120b5da9499SMatthew 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);
3121b5da9499SMatthew G. Knepley       }
3122b5da9499SMatthew G. Knepley #endif
3123b5da9499SMatthew G. Knepley       ++newp;
3124b5da9499SMatthew G. Knepley     }
3125b5da9499SMatthew G. Knepley     /* Split Edges have 2 vertices and the same faces as the parent */
3126b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
3127b5da9499SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
3128b5da9499SMatthew G. Knepley 
3129b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
3130b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
3131b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
3132b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
3133b5da9499SMatthew G. Knepley 
3134b5da9499SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
3135b5da9499SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
3136b5da9499SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
3137b5da9499SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
3138b5da9499SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3139b5da9499SMatthew G. Knepley #if 1
3140b5da9499SMatthew 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);
3141b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
3142b5da9499SMatthew 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);
3143b5da9499SMatthew G. Knepley         }
3144b5da9499SMatthew G. Knepley #endif
3145b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
3146b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
3147b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
3148b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
3149b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
3150b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
3151b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
3152b5da9499SMatthew G. Knepley             if (cone[c] == e) break;
3153b5da9499SMatthew G. Knepley           }
3154b5da9499SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
3155b5da9499SMatthew G. Knepley         }
3156b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
3157b5da9499SMatthew G. Knepley #if 1
3158b5da9499SMatthew 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);
3159b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
3160b5da9499SMatthew 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);
3161b5da9499SMatthew G. Knepley         }
3162b5da9499SMatthew G. Knepley #endif
3163b5da9499SMatthew G. Knepley       }
3164b5da9499SMatthew G. Knepley     }
316586f0afeeSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
3166b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
3167b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
3168b5da9499SMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
3169b5da9499SMatthew G. Knepley 
3170b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
3171b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
3172b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
3173b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
3174b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
3175b5da9499SMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
3176b5da9499SMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
3177b5da9499SMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
3178b5da9499SMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
3179b5da9499SMatthew G. Knepley 
3180b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
3181b5da9499SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
3182b5da9499SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
3183b5da9499SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3184b5da9499SMatthew G. Knepley #if 1
3185b5da9499SMatthew 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);
3186b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
3187b5da9499SMatthew 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);
3188b5da9499SMatthew G. Knepley         }
3189b5da9499SMatthew G. Knepley #endif
3190b5da9499SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
3191b5da9499SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
3192b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
3193b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
3194b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
3195b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
3196b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
319786f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
3198*e5337592SStefano Zampini           er = GetTriMidEdgeInverse_Static(ornt[c], r);
3199b5da9499SMatthew G. Knepley           if (er == eint[c]) {
3200b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
3201b5da9499SMatthew G. Knepley           } else {
3202b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
3203b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
3204b5da9499SMatthew G. Knepley           }
3205b5da9499SMatthew G. Knepley         }
3206b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
3207b5da9499SMatthew G. Knepley #if 1
3208b5da9499SMatthew 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);
3209b5da9499SMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
3210b5da9499SMatthew 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);
3211b5da9499SMatthew G. Knepley         }
3212b5da9499SMatthew G. Knepley #endif
3213b5da9499SMatthew G. Knepley       }
3214b5da9499SMatthew G. Knepley     }
3215b5da9499SMatthew G. Knepley     /* Interior edges have 2 vertices and 4 faces */
3216b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
3217b5da9499SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
3218b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
32194a40f731SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
3220b5da9499SMatthew G. Knepley 
3221b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
3222b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
3223b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
322442525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
3225b5da9499SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
3226b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
322742525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
3228b5da9499SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
3229b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3230b5da9499SMatthew G. Knepley #if 1
3231b5da9499SMatthew 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);
3232b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3233b5da9499SMatthew 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);
3234b5da9499SMatthew G. Knepley       }
3235b5da9499SMatthew G. Knepley #endif
3236b5da9499SMatthew G. Knepley       supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
3237b5da9499SMatthew G. Knepley       supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
3238b5da9499SMatthew G. Knepley       supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
3239b5da9499SMatthew G. Knepley       supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
3240b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3241b5da9499SMatthew G. Knepley #if 1
3242b5da9499SMatthew 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);
3243b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3244b5da9499SMatthew 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);
3245b5da9499SMatthew G. Knepley       }
3246b5da9499SMatthew G. Knepley #endif
3247b5da9499SMatthew G. Knepley     }
3248b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
3249b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
3250b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
3251b5da9499SMatthew G. Knepley       const PetscInt *support, *cone;
3252b5da9499SMatthew G. Knepley       PetscInt        size, s;
3253b5da9499SMatthew G. Knepley 
3254b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
3255b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
3256b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
3257b5da9499SMatthew G. Knepley         PetscInt r = 0;
3258b5da9499SMatthew G. Knepley 
3259b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
3260b5da9499SMatthew G. Knepley         if (cone[1] == v) r = 1;
3261b5da9499SMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
3262b5da9499SMatthew G. Knepley       }
3263b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
3264b5da9499SMatthew G. Knepley #if 1
3265b5da9499SMatthew 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);
3266b5da9499SMatthew G. Knepley       for (p = 0; p < size; ++p) {
3267b5da9499SMatthew 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);
3268b5da9499SMatthew G. Knepley       }
3269b5da9499SMatthew G. Knepley #endif
3270b5da9499SMatthew G. Knepley     }
3271b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + face*2 + 0/1 supports */
3272b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
3273b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
3274b5da9499SMatthew G. Knepley       const PetscInt *cone, *support;
3275b5da9499SMatthew G. Knepley       PetscInt       *star = NULL, starSize, cellSize = 0, coneSize, size, s;
3276b5da9499SMatthew G. Knepley 
3277b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
3278b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
3279b5da9499SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
3280b5da9499SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
3281b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
3282b5da9499SMatthew G. Knepley         PetscInt r = 0;
3283b5da9499SMatthew G. Knepley 
3284b5da9499SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
3285b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
3286b5da9499SMatthew G. Knepley         for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
3287b5da9499SMatthew G. Knepley         supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
3288b5da9499SMatthew G. Knepley         supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
3289b5da9499SMatthew G. Knepley       }
3290b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
3291b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
3292b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
3293b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
3294b5da9499SMatthew G. Knepley 
3295b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
3296b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
3297b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
3298b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
3299b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
330042525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
3301b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
3302b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
3303b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
330442525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
330542525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
3306b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);}
3307b5da9499SMatthew G. Knepley         }
3308b5da9499SMatthew G. Knepley       }
3309b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
3310b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
3311b5da9499SMatthew G. Knepley #if 1
3312b5da9499SMatthew 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);
3313b5da9499SMatthew G. Knepley       for (p = 0; p < 2+size*2+cellSize; ++p) {
3314b5da9499SMatthew 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);
3315b5da9499SMatthew G. Knepley       }
3316b5da9499SMatthew G. Knepley #endif
3317b5da9499SMatthew G. Knepley     }
3318b5da9499SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
3319b5da9499SMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
3320b5da9499SMatthew G. Knepley     break;
33219b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
33226ce3c06aSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
33236ce3c06aSMatthew G. Knepley     /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
33246ce3c06aSMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
33256ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
33266ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
33276ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
33286ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
33296ce3c06aSMatthew G. Knepley 
33306ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
33316ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
33326ce3c06aSMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
33336ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
33346ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
33356ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
33366ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
33376ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
33386ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
33396ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
33406ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
33416ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
33426ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
33436ce3c06aSMatthew G. Knepley #if 1
33446ce3c06aSMatthew 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);
33456ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
33466ce3c06aSMatthew 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);
33476ce3c06aSMatthew G. Knepley       }
33486ce3c06aSMatthew G. Knepley #endif
33496ce3c06aSMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
33506ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
33516ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
33526ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
33536ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
33546ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
33556ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
33566ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
33576ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
33586ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
33596ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
33606ce3c06aSMatthew G. Knepley #if 1
33616ce3c06aSMatthew 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);
33626ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
33636ce3c06aSMatthew 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);
33646ce3c06aSMatthew G. Knepley       }
33656ce3c06aSMatthew G. Knepley #endif
33666ce3c06aSMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
33676ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
33686ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
33696ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
33706ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
33716ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
33726ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
33736ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
33746ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
33756ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
33766ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
33776ce3c06aSMatthew G. Knepley #if 1
33786ce3c06aSMatthew 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);
33796ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
33806ce3c06aSMatthew 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);
33816ce3c06aSMatthew G. Knepley       }
33826ce3c06aSMatthew G. Knepley #endif
33836ce3c06aSMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
33846ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
33856ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
33866ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
33876ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
33886ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
33896ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
33906ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
33916ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
33926ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
33936ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
33946ce3c06aSMatthew G. Knepley #if 1
33956ce3c06aSMatthew 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);
33966ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
33976ce3c06aSMatthew 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);
33986ce3c06aSMatthew G. Knepley       }
33996ce3c06aSMatthew G. Knepley #endif
34006ce3c06aSMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
34016ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
34026ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
34039ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
3404*e5337592SStefano Zampini       orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0);
34059ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
34069ddff745SMatthew G. Knepley       orntNew[2] = 0;
34079ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
34089ddff745SMatthew G. Knepley       orntNew[3] = 2;
34096ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
34106ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
34116ce3c06aSMatthew G. Knepley #if 1
34126ce3c06aSMatthew 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);
34136ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
34146ce3c06aSMatthew 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);
34156ce3c06aSMatthew G. Knepley       }
34166ce3c06aSMatthew G. Knepley #endif
34176ce3c06aSMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
34186ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
34196ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
34209ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
34219ddff745SMatthew G. Knepley       orntNew[1] = 1;
34229ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
34236ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
34249ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
3425*e5337592SStefano Zampini       orntNew[3] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 0)+1) : GetTriMidEdge_Static(ornt[3], 0);
34266ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
34276ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
34286ce3c06aSMatthew G. Knepley #if 1
34296ce3c06aSMatthew 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);
34306ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
34316ce3c06aSMatthew 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);
34326ce3c06aSMatthew G. Knepley       }
34336ce3c06aSMatthew G. Knepley #endif
34346ce3c06aSMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
34356ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
34366ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
34379ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
3438*e5337592SStefano Zampini       orntNew[1] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2);
34399ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
34409ddff745SMatthew G. Knepley       orntNew[2] = -3;
34419ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
34429ddff745SMatthew G. Knepley       orntNew[3] = -2;
34436ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
34446ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
34456ce3c06aSMatthew G. Knepley #if 1
34466ce3c06aSMatthew 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);
34476ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
34486ce3c06aSMatthew 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);
34496ce3c06aSMatthew G. Knepley       }
34506ce3c06aSMatthew G. Knepley #endif
34516ce3c06aSMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
34526ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
34536ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
34549ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
34556ce3c06aSMatthew G. Knepley       orntNew[1] = -3;
34569ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
3457*e5337592SStefano Zampini       orntNew[2] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 0)+1) : GetTriMidEdge_Static(ornt[1], 0);
34589ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
34599ddff745SMatthew G. Knepley       orntNew[3] = -3;
34606ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
34616ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
34626ce3c06aSMatthew G. Knepley #if 1
34636ce3c06aSMatthew 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);
34646ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
34656ce3c06aSMatthew 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);
34666ce3c06aSMatthew G. Knepley       }
34676ce3c06aSMatthew G. Knepley #endif
34686ce3c06aSMatthew G. Knepley     }
34696ce3c06aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
34706ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
34716ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4;
3472d3a1cc75SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
34733b61eb6dSMatthew G. Knepley       PetscInt        coneNew[5], orntNew[5], o, of, i;
34746ce3c06aSMatthew G. Knepley 
34756ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
34766ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
3477d3a1cc75SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
3478084f9c62SMatthew G. Knepley       o = ornt[0] < 0 ? -1 : 1;
34796ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
34806ce3c06aSMatthew G. Knepley         coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r);
34816ce3c06aSMatthew G. Knepley         orntNew[0] = ornt[0];
34826ce3c06aSMatthew G. Knepley         coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r);
34836ce3c06aSMatthew G. Knepley         orntNew[1] = ornt[1];
3484084f9c62SMatthew G. Knepley         of = fornt[GetTriEdge_Static(ornt[0], r)]       < 0 ? -1 : 1;
34853b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], r)       + 2;
34863b61eb6dSMatthew 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);
34873b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
34883b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2;
34893b61eb6dSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r);
34903b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
34913b61eb6dSMatthew G. Knepley         of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1;
34923b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2;
34933b61eb6dSMatthew 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);
34943b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
34956ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
34966ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
34976ce3c06aSMatthew G. Knepley #if 1
34986ce3c06aSMatthew 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);
34996ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
35006ce3c06aSMatthew 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);
35016ce3c06aSMatthew G. Knepley         }
35026ce3c06aSMatthew G. Knepley         for (p = 2; p < 5; ++p) {
35036ce3c06aSMatthew 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);
35046ce3c06aSMatthew G. Knepley         }
35056ce3c06aSMatthew G. Knepley #endif
35066ce3c06aSMatthew G. Knepley       }
35076ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3;
35086ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
35096ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3;
35106ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
35113b61eb6dSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1;
35126ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
35133b61eb6dSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2;
35146ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
35153b61eb6dSMatthew G. Knepley       coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0;
35166ce3c06aSMatthew G. Knepley       orntNew[4] = 0;
35176ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
35186ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
35196ce3c06aSMatthew G. Knepley #if 1
35206ce3c06aSMatthew 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);
35216ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
35226ce3c06aSMatthew 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);
35236ce3c06aSMatthew G. Knepley       }
35246ce3c06aSMatthew G. Knepley       for (p = 2; p < 5; ++p) {
35256ce3c06aSMatthew 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);
35266ce3c06aSMatthew G. Knepley       }
35276ce3c06aSMatthew G. Knepley #endif
35286ce3c06aSMatthew G. Knepley     }
35296ce3c06aSMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
35306ce3c06aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
3531854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
35326ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
35336ce3c06aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
35346ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
35356ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
35366ce3c06aSMatthew G. Knepley 
35376ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
35386ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
35396ce3c06aSMatthew G. Knepley       /* A triangle */
35406ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
35416ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
35426ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
35436ce3c06aSMatthew G. Knepley       orntNew[1] = -2;
35446ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
35456ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
35466ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
35476ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
35486ce3c06aSMatthew G. Knepley #if 1
35496ce3c06aSMatthew 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);
35506ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
35516ce3c06aSMatthew 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);
35526ce3c06aSMatthew G. Knepley       }
35536ce3c06aSMatthew G. Knepley #endif
35546ce3c06aSMatthew G. Knepley       /* B triangle */
35556ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
35566ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
35576ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
35586ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
35596ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
35606ce3c06aSMatthew G. Knepley       orntNew[2] = -2;
35616ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
35626ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
35636ce3c06aSMatthew G. Knepley #if 1
35646ce3c06aSMatthew 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);
35656ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
35666ce3c06aSMatthew 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);
35676ce3c06aSMatthew G. Knepley       }
35686ce3c06aSMatthew G. Knepley #endif
35696ce3c06aSMatthew G. Knepley       /* C triangle */
35706ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
35716ce3c06aSMatthew G. Knepley       orntNew[0] = -2;
35726ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
35736ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
35746ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
35756ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
35766ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
35776ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
35786ce3c06aSMatthew G. Knepley #if 1
35796ce3c06aSMatthew 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);
35806ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
35816ce3c06aSMatthew 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);
35826ce3c06aSMatthew G. Knepley       }
35836ce3c06aSMatthew G. Knepley #endif
35846ce3c06aSMatthew G. Knepley       /* D triangle */
35856ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
35866ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
35876ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
35886ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
35896ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
35906ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
35916ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
35926ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
35936ce3c06aSMatthew G. Knepley #if 1
35946ce3c06aSMatthew 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);
35956ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
35966ce3c06aSMatthew 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);
35976ce3c06aSMatthew G. Knepley       }
35986ce3c06aSMatthew G. Knepley #endif
35996ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
36006ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
36016ce3c06aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
36026ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
36039ddff745SMatthew G. Knepley           PetscInt subf;
36046ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
36056ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
36066ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
36076ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
36086ce3c06aSMatthew G. Knepley             if (cone[c] == f) break;
36096ce3c06aSMatthew G. Knepley           }
36109ddff745SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
36116ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
36129ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
36136ce3c06aSMatthew G. Knepley           } else {
36149ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf);
36156ce3c06aSMatthew G. Knepley           }
36166ce3c06aSMatthew G. Knepley         }
36176ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
36186ce3c06aSMatthew G. Knepley #if 1
36199ddff745SMatthew 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);
36206ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
36216ce3c06aSMatthew 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);
36226ce3c06aSMatthew G. Knepley         }
36236ce3c06aSMatthew G. Knepley #endif
36246ce3c06aSMatthew G. Knepley       }
36256ce3c06aSMatthew G. Knepley     }
36266ce3c06aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
36276ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
36286ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8;
36296ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
36306ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
36316ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
36326ce3c06aSMatthew G. Knepley 
36336ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
36346ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
36356ce3c06aSMatthew G. Knepley       /* Face A: {c, a, d} */
3636*e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
36376ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
3638*e5337592SStefano Zampini       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
36396ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
3640*e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2);
36416ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
36426ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
36436ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
36446ce3c06aSMatthew G. Knepley #if 1
36456ce3c06aSMatthew 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);
36466ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
36476ce3c06aSMatthew 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);
36486ce3c06aSMatthew G. Knepley       }
36496ce3c06aSMatthew G. Knepley #endif
36506ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
36516ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
36526ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
36536ce3c06aSMatthew G. Knepley #if 1
36546ce3c06aSMatthew 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);
36556ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
36566ce3c06aSMatthew 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);
36576ce3c06aSMatthew G. Knepley       }
36586ce3c06aSMatthew G. Knepley #endif
36596ce3c06aSMatthew G. Knepley       ++newp;
36606ce3c06aSMatthew G. Knepley       /* Face B: {a, b, e} */
3661*e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
36626ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
3663*e5337592SStefano Zampini       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0);
36646ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
3665*e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
36666ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
36676ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
36686ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
36696ce3c06aSMatthew G. Knepley #if 1
36706ce3c06aSMatthew 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);
36716ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
36726ce3c06aSMatthew 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);
36736ce3c06aSMatthew G. Knepley       }
36746ce3c06aSMatthew G. Knepley #endif
36756ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
36766ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
36776ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
36786ce3c06aSMatthew G. Knepley #if 1
36796ce3c06aSMatthew 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);
36806ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
36816ce3c06aSMatthew 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);
36826ce3c06aSMatthew G. Knepley       }
36836ce3c06aSMatthew G. Knepley #endif
36846ce3c06aSMatthew G. Knepley       ++newp;
36856ce3c06aSMatthew G. Knepley       /* Face C: {c, f, b} */
3686*e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
36876ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
3688*e5337592SStefano Zampini       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
36896ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
3690*e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1);
36916ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
36926ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
36936ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
36946ce3c06aSMatthew G. Knepley #if 1
36956ce3c06aSMatthew 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);
36966ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
36976ce3c06aSMatthew 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);
36986ce3c06aSMatthew G. Knepley       }
36996ce3c06aSMatthew G. Knepley #endif
37006ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
37016ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
37026ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
37036ce3c06aSMatthew G. Knepley #if 1
37046ce3c06aSMatthew 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);
37056ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
37066ce3c06aSMatthew 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);
37076ce3c06aSMatthew G. Knepley       }
37086ce3c06aSMatthew G. Knepley #endif
37096ce3c06aSMatthew G. Knepley       ++newp;
37106ce3c06aSMatthew G. Knepley       /* Face D: {d, e, f} */
3711*e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0);
37126ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
3713*e5337592SStefano Zampini       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
37146ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
3715*e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
37166ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
37176ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37186ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
37196ce3c06aSMatthew G. Knepley #if 1
37206ce3c06aSMatthew 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);
37216ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
37226ce3c06aSMatthew 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);
37236ce3c06aSMatthew G. Knepley       }
37246ce3c06aSMatthew G. Knepley #endif
37256ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
37266ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
37276ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
37286ce3c06aSMatthew G. Knepley #if 1
37296ce3c06aSMatthew 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);
37306ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
37316ce3c06aSMatthew 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);
37326ce3c06aSMatthew G. Knepley       }
37336ce3c06aSMatthew G. Knepley #endif
37346ce3c06aSMatthew G. Knepley       ++newp;
37356ce3c06aSMatthew G. Knepley       /* Face E: {d, f, a} */
3736*e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
37376ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
37386ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
37399ddff745SMatthew G. Knepley       orntNew[1] = -2;
3740*e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
37416ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
37426ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37436ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
37446ce3c06aSMatthew G. Knepley #if 1
37456ce3c06aSMatthew 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);
37466ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
37476ce3c06aSMatthew 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);
37486ce3c06aSMatthew G. Knepley       }
37496ce3c06aSMatthew G. Knepley #endif
37506ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
37516ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
37526ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
37536ce3c06aSMatthew G. Knepley #if 1
37546ce3c06aSMatthew 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);
37556ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
37566ce3c06aSMatthew 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);
37576ce3c06aSMatthew G. Knepley       }
37586ce3c06aSMatthew G. Knepley #endif
37596ce3c06aSMatthew G. Knepley       ++newp;
37606ce3c06aSMatthew G. Knepley       /* Face F: {c, a, f} */
3761*e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
37626ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
37636ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
37649ddff745SMatthew G. Knepley       orntNew[1] = 0;
3765*e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
37669ddff745SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
37676ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37686ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
37696ce3c06aSMatthew G. Knepley #if 1
37706ce3c06aSMatthew 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);
37716ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
37726ce3c06aSMatthew 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);
37736ce3c06aSMatthew G. Knepley       }
37746ce3c06aSMatthew G. Knepley #endif
37756ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
37766ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
37776ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
37786ce3c06aSMatthew G. Knepley #if 1
37796ce3c06aSMatthew 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);
37806ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
37816ce3c06aSMatthew 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);
37826ce3c06aSMatthew G. Knepley       }
37836ce3c06aSMatthew G. Knepley #endif
37846ce3c06aSMatthew G. Knepley       ++newp;
37856ce3c06aSMatthew G. Knepley       /* Face G: {e, a, f} */
3786*e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
37876ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
37886ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
37899ddff745SMatthew G. Knepley       orntNew[1] = 0;
3790*e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
37916ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
37926ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37936ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
37946ce3c06aSMatthew G. Knepley #if 1
37956ce3c06aSMatthew 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);
37966ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
37976ce3c06aSMatthew 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);
37986ce3c06aSMatthew G. Knepley       }
37996ce3c06aSMatthew G. Knepley #endif
38006ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
38016ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
38026ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
38036ce3c06aSMatthew G. Knepley #if 1
38046ce3c06aSMatthew 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);
38056ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
38066ce3c06aSMatthew 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);
38076ce3c06aSMatthew G. Knepley       }
38086ce3c06aSMatthew G. Knepley #endif
38096ce3c06aSMatthew G. Knepley       ++newp;
38106ce3c06aSMatthew G. Knepley       /* Face H: {a, b, f} */
3811*e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
38126ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
3813*e5337592SStefano Zampini       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
38146ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
38156ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
38169ddff745SMatthew G. Knepley       orntNew[2] = -2;
38176ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
38186ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
38196ce3c06aSMatthew G. Knepley #if 1
38206ce3c06aSMatthew 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);
38216ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
38226ce3c06aSMatthew 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);
38236ce3c06aSMatthew G. Knepley       }
38246ce3c06aSMatthew G. Knepley #endif
38256ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
38266ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
38276ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
38286ce3c06aSMatthew G. Knepley #if 1
38296ce3c06aSMatthew 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);
38306ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
38316ce3c06aSMatthew 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);
38326ce3c06aSMatthew G. Knepley       }
38336ce3c06aSMatthew G. Knepley #endif
38346ce3c06aSMatthew G. Knepley       ++newp;
38356ce3c06aSMatthew G. Knepley     }
38366ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
38376ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
38386ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
38396ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
38406ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
38416ce3c06aSMatthew G. Knepley 
38426ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
38436ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
38446ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
38456ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
38466ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
38476ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
38486ce3c06aSMatthew G. Knepley 
38496ce3c06aSMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
38506ce3c06aSMatthew G. Knepley         orntNew[0]   = ornt[0];
38516ce3c06aSMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
38526ce3c06aSMatthew G. Knepley         orntNew[1]   = ornt[1];
38536ce3c06aSMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax);
38546ce3c06aSMatthew G. Knepley         orntNew[2+r] = 0;
38556ce3c06aSMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd      - eMax) + (f - fMax);
38566ce3c06aSMatthew G. Knepley         orntNew[3-r] = 0;
38576ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
38586ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
38596ce3c06aSMatthew G. Knepley #if 1
38606ce3c06aSMatthew 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);
38616ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
38626ce3c06aSMatthew 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);
38636ce3c06aSMatthew G. Knepley         }
38646ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
38656ce3c06aSMatthew 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);
38666ce3c06aSMatthew G. Knepley         }
38676ce3c06aSMatthew G. Knepley #endif
38686ce3c06aSMatthew G. Knepley         for (s = 0; s < size; ++s) {
3869d3a1cc75SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
3870084f9c62SMatthew G. Knepley           PetscInt        o, of;
38716ce3c06aSMatthew G. Knepley 
38726ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
38736ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
3874084f9c62SMatthew G. Knepley           o = orntCell[0] < 0 ? -1 : 1;
38756ce3c06aSMatthew G. Knepley           for (c = 2; c < 5; ++c) if (coneCell[c] == f) break;
38766ce3c06aSMatthew 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]);
3877d3a1cc75SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
3878084f9c62SMatthew G. Knepley           of = fornt[c-2] < 0 ? -1 : 1;
3879084f9c62SMatthew 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;
38806ce3c06aSMatthew G. Knepley         }
38816ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
38826ce3c06aSMatthew G. Knepley #if 1
38836ce3c06aSMatthew 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);
38846ce3c06aSMatthew G. Knepley         for (p = 0; p < size; ++p) {
38856ce3c06aSMatthew 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);
38866ce3c06aSMatthew G. Knepley         }
38876ce3c06aSMatthew G. Knepley #endif
38886ce3c06aSMatthew G. Knepley       }
38896ce3c06aSMatthew G. Knepley     }
38906ce3c06aSMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
38916ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
38926ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3;
38936ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
38946ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
38956ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
38966ce3c06aSMatthew G. Knepley 
38976ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
38986ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
38996ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
3900b598a9d5SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3;
39016ce3c06aSMatthew G. Knepley         orntNew[0] = 0;
3902b598a9d5SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3;
39036ce3c06aSMatthew G. Knepley         orntNew[1] = 0;
3904b598a9d5SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax);
39056ce3c06aSMatthew G. Knepley         orntNew[2] = 0;
3906b598a9d5SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r]       - fMax);
39076ce3c06aSMatthew G. Knepley         orntNew[3] = 0;
39086ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
39096ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
39106ce3c06aSMatthew G. Knepley #if 1
39116ce3c06aSMatthew 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);
39126ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
39136ce3c06aSMatthew 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);
39146ce3c06aSMatthew G. Knepley         }
39156ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
39166ce3c06aSMatthew 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);
39176ce3c06aSMatthew G. Knepley         }
39186ce3c06aSMatthew G. Knepley #endif
39196ce3c06aSMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r);
39206ce3c06aSMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3;
39216ce3c06aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
39226ce3c06aSMatthew G. Knepley #if 1
39236ce3c06aSMatthew 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);
39246ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
39256ce3c06aSMatthew 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);
39266ce3c06aSMatthew G. Knepley         }
39276ce3c06aSMatthew G. Knepley #endif
39286ce3c06aSMatthew G. Knepley       }
39296ce3c06aSMatthew G. Knepley     }
39306ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
39316ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
39326ce3c06aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
39336ce3c06aSMatthew G. Knepley 
39346ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
39356ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
39366ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
39376ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
39386ce3c06aSMatthew G. Knepley 
39396ce3c06aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
39406ce3c06aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
39416ce3c06aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
39426ce3c06aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
39436ce3c06aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
39446ce3c06aSMatthew G. Knepley #if 1
39456ce3c06aSMatthew 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);
39466ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
39476ce3c06aSMatthew 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);
39486ce3c06aSMatthew G. Knepley         }
39496ce3c06aSMatthew G. Knepley #endif
39506ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
39516ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
39526ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
39536ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
39546ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
39556ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
39566ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == e) break;
39576ce3c06aSMatthew G. Knepley           if (support[s] < fMax) {
39586ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
39596ce3c06aSMatthew G. Knepley           } else {
39606ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
39616ce3c06aSMatthew G. Knepley           }
39626ce3c06aSMatthew G. Knepley         }
39636ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
39646ce3c06aSMatthew G. Knepley #if 1
39656ce3c06aSMatthew 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);
39666ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
39676ce3c06aSMatthew 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);
39686ce3c06aSMatthew G. Knepley         }
39696ce3c06aSMatthew G. Knepley #endif
39706ce3c06aSMatthew G. Knepley       }
39716ce3c06aSMatthew G. Knepley     }
39726ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
39736ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
39746ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
39756ce3c06aSMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
39766ce3c06aSMatthew G. Knepley 
39776ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
39786ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
39796ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
39806ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
39816ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
39826ce3c06aSMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
39836ce3c06aSMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
39846ce3c06aSMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
39856ce3c06aSMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
39866ce3c06aSMatthew G. Knepley 
39876ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
39886ce3c06aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
39896ce3c06aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
39906ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
39916ce3c06aSMatthew G. Knepley #if 1
39926ce3c06aSMatthew 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);
39936ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
39946ce3c06aSMatthew 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);
39956ce3c06aSMatthew G. Knepley         }
39966ce3c06aSMatthew G. Knepley #endif
39976ce3c06aSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
39986ce3c06aSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
39996ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
40006ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
40016ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
40026ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
40036ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
40046ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
40056ce3c06aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
4006*e5337592SStefano Zampini             er = GetTriMidEdgeInverse_Static(ornt[c], r);
40076ce3c06aSMatthew G. Knepley             if (er == eint[c]) {
40086ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
40096ce3c06aSMatthew G. Knepley             } else {
40106ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
40116ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
40126ce3c06aSMatthew G. Knepley             }
40136ce3c06aSMatthew G. Knepley           } else {
4014b598a9d5SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3;
40156ce3c06aSMatthew G. Knepley           }
40166ce3c06aSMatthew G. Knepley         }
40176ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
40186ce3c06aSMatthew G. Knepley #if 1
40196ce3c06aSMatthew 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);
40206ce3c06aSMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
40216ce3c06aSMatthew 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);
40226ce3c06aSMatthew G. Knepley         }
40236ce3c06aSMatthew G. Knepley #endif
40246ce3c06aSMatthew G. Knepley       }
40256ce3c06aSMatthew G. Knepley     }
40266ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
40276ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
40286ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
40296ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
40306ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
40316ce3c06aSMatthew G. Knepley 
40326ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
40336ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
40346ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
40356ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
40366ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
40376ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
40386ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
40396ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
40406ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
40416ce3c06aSMatthew G. Knepley #if 1
40426ce3c06aSMatthew 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);
40436ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
40446ce3c06aSMatthew 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);
40456ce3c06aSMatthew G. Knepley       }
40466ce3c06aSMatthew G. Knepley #endif
40476ce3c06aSMatthew G. Knepley       supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
40486ce3c06aSMatthew G. Knepley       supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
40496ce3c06aSMatthew G. Knepley       supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
40506ce3c06aSMatthew G. Knepley       supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
40516ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
40526ce3c06aSMatthew G. Knepley #if 1
40536ce3c06aSMatthew 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);
40546ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
40556ce3c06aSMatthew 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);
40566ce3c06aSMatthew G. Knepley       }
40576ce3c06aSMatthew G. Knepley #endif
40586ce3c06aSMatthew G. Knepley     }
40596ce3c06aSMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
40606ce3c06aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
40616ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
40626ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
40636ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
40646ce3c06aSMatthew G. Knepley 
40656ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
40666ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
40676ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
40686ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
40696ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
40706ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
40716ce3c06aSMatthew G. Knepley #if 1
40726ce3c06aSMatthew 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);
40736ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
40746ce3c06aSMatthew 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);
40756ce3c06aSMatthew G. Knepley       }
40766ce3c06aSMatthew G. Knepley #endif
40776ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
40786ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
40796ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
40806ce3c06aSMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
40816ce3c06aSMatthew 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]);
40826ce3c06aSMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2;
40836ce3c06aSMatthew G. Knepley       }
40846ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
40856ce3c06aSMatthew G. Knepley #if 1
40866ce3c06aSMatthew 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);
40876ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
40886ce3c06aSMatthew 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);
40896ce3c06aSMatthew G. Knepley       }
40906ce3c06aSMatthew G. Knepley #endif
40916ce3c06aSMatthew G. Knepley     }
40926ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
40936ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
40946ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
4095623f4348SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
40966ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
40976ce3c06aSMatthew G. Knepley 
40986ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
40996ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
41006ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
41016ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
41026ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
41036ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
41046ce3c06aSMatthew G. Knepley #if 1
41056ce3c06aSMatthew 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);
41066ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
41076ce3c06aSMatthew 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);
41086ce3c06aSMatthew G. Knepley       }
41096ce3c06aSMatthew G. Knepley #endif
41106ce3c06aSMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0;
41116ce3c06aSMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1;
41126ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
41136ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
41146ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
4115623f4348SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
41166ce3c06aSMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
41176ce3c06aSMatthew 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]);
4118b598a9d5SMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2;
4119b598a9d5SMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3;
41206ce3c06aSMatthew G. Knepley       }
41216ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
41226ce3c06aSMatthew G. Knepley #if 1
41236ce3c06aSMatthew 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);
41246ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
41256ce3c06aSMatthew 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);
41266ce3c06aSMatthew G. Knepley       }
41276ce3c06aSMatthew G. Knepley #endif
41286ce3c06aSMatthew G. Knepley     }
41296ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
41306ce3c06aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
41316ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
41326ce3c06aSMatthew G. Knepley       const PetscInt *support, *cone;
41336ce3c06aSMatthew G. Knepley       PetscInt        size, s;
41346ce3c06aSMatthew G. Knepley 
41356ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
41366ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
41376ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
41386ce3c06aSMatthew G. Knepley         PetscInt r = 0;
41396ce3c06aSMatthew G. Knepley 
41406ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
41416ce3c06aSMatthew G. Knepley         if (cone[1] == v) r = 1;
41426ce3c06aSMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
41436ce3c06aSMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax);
41446ce3c06aSMatthew G. Knepley       }
41456ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
41466ce3c06aSMatthew G. Knepley #if 1
41476ce3c06aSMatthew 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);
41486ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
41496ce3c06aSMatthew 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);
41506ce3c06aSMatthew G. Knepley       }
41516ce3c06aSMatthew G. Knepley #endif
41526ce3c06aSMatthew G. Knepley     }
41536ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
41546ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
41556ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
41566ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support;
41576ce3c06aSMatthew G. Knepley       PetscInt       *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s;
41586ce3c06aSMatthew G. Knepley 
41596ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
41606ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
41616ce3c06aSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
41626ce3c06aSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
41636ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
41646ce3c06aSMatthew G. Knepley         PetscInt r = 0;
41656ce3c06aSMatthew G. Knepley 
41666ce3c06aSMatthew G. Knepley         if (support[s] < fMax) {
41676ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
41686ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
41696ce3c06aSMatthew G. Knepley           for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
41706ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
41716ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
41726ce3c06aSMatthew G. Knepley           faceSize += 2;
41736ce3c06aSMatthew G. Knepley         } else {
41746ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax);
41756ce3c06aSMatthew G. Knepley           ++faceSize;
41766ce3c06aSMatthew G. Knepley         }
41776ce3c06aSMatthew G. Knepley       }
41786ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
41796ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
41806ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
41816ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
41826ce3c06aSMatthew G. Knepley 
41836ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
41846ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
41856ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
41866ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
41876ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
41886ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
41896ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
41906ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
41916ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
41926ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
41936ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
41946ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);}
41956ce3c06aSMatthew G. Knepley         }
41966ce3c06aSMatthew G. Knepley       }
41976ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
41986ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
41996ce3c06aSMatthew G. Knepley #if 1
42006ce3c06aSMatthew 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);
42016ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+faceSize+cellSize; ++p) {
42026ce3c06aSMatthew 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);
42036ce3c06aSMatthew G. Knepley       }
42046ce3c06aSMatthew G. Knepley #endif
42056ce3c06aSMatthew G. Knepley     }
42066ce3c06aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
42076ce3c06aSMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
42086ce3c06aSMatthew G. Knepley     break;
4209*e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_3D:
4210*e5337592SStefano Zampini     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
4211*e5337592SStefano Zampini     /* All cells have 6 faces */
4212*e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
4213*e5337592SStefano Zampini       const PetscInt  newp = cStartNew + (c - cStart)*4;
4214*e5337592SStefano Zampini       const PetscInt *cone, *ornt;
4215*e5337592SStefano Zampini       PetscInt        coneNew[6];
4216*e5337592SStefano Zampini       PetscInt        orntNew[6];
4217*e5337592SStefano Zampini 
4218*e5337592SStefano Zampini       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
4219*e5337592SStefano Zampini       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
4220*e5337592SStefano Zampini       /* A hex */
4221*e5337592SStefano Zampini       coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */
4222*e5337592SStefano Zampini       orntNew[0] = ornt[0] < 0 ? -1 : 1;
4223*e5337592SStefano Zampini       coneNew[1] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 3;               /* T */
4224*e5337592SStefano Zampini       orntNew[1] = -4;
4225*e5337592SStefano Zampini       coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */
4226*e5337592SStefano Zampini       orntNew[2] = ornt[2] < 0 ? -1 : 1;
4227*e5337592SStefano Zampini       coneNew[3] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 0;               /* K */
4228*e5337592SStefano Zampini       orntNew[3] = -1;
4229*e5337592SStefano Zampini       coneNew[4] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 2;               /* R */
4230*e5337592SStefano Zampini       orntNew[4] = 0;
4231*e5337592SStefano Zampini       coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */
4232*e5337592SStefano Zampini       orntNew[5] = ornt[1] < 0 ? -1 : 1;
4233*e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
4234*e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
4235*e5337592SStefano Zampini #if 1
4236*e5337592SStefano Zampini       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);
4237*e5337592SStefano Zampini       for (p = 0; p < 6; ++p) {
4238*e5337592SStefano Zampini         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);
4239*e5337592SStefano Zampini       }
4240*e5337592SStefano Zampini #endif
4241*e5337592SStefano Zampini       /* B hex */
4242*e5337592SStefano Zampini       coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */
4243*e5337592SStefano Zampini       orntNew[0] = ornt[0] < 0 ? -2 : 0;
4244*e5337592SStefano Zampini       coneNew[1] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 4;               /* T */
4245*e5337592SStefano Zampini       orntNew[1] = 0;
4246*e5337592SStefano Zampini       coneNew[2] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 0;               /* F */
4247*e5337592SStefano Zampini       orntNew[2] = 0;
4248*e5337592SStefano Zampini       coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */
4249*e5337592SStefano Zampini       orntNew[3] = ornt[3] < 0 ? -2 : 0;
4250*e5337592SStefano Zampini       coneNew[4] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 1;               /* R */
4251*e5337592SStefano Zampini       orntNew[4] = 0;
4252*e5337592SStefano Zampini       coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */
4253*e5337592SStefano Zampini       orntNew[5] = ornt[1] < 0 ? -4 : 2;
4254*e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
4255*e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
4256*e5337592SStefano Zampini #if 1
4257*e5337592SStefano Zampini       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);
4258*e5337592SStefano Zampini       for (p = 0; p < 6; ++p) {
4259*e5337592SStefano Zampini         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);
4260*e5337592SStefano Zampini       }
4261*e5337592SStefano Zampini #endif
4262*e5337592SStefano Zampini       /* C hex */
4263*e5337592SStefano Zampini       coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */
4264*e5337592SStefano Zampini       orntNew[0] = ornt[0] < 0 ? -4 : 2;
4265*e5337592SStefano Zampini       coneNew[1] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 5;               /* T */
4266*e5337592SStefano Zampini       orntNew[1] = -4;
4267*e5337592SStefano Zampini       coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */
4268*e5337592SStefano Zampini       orntNew[2] = ornt[2] < 0 ? -2 : 0;
4269*e5337592SStefano Zampini       coneNew[3] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 1;               /* K */
4270*e5337592SStefano Zampini       orntNew[3] = -1;
4271*e5337592SStefano Zampini       coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */
4272*e5337592SStefano Zampini       orntNew[4] = ornt[3] < 0 ? -1 : 1;
4273*e5337592SStefano Zampini       coneNew[5] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 2;               /* L */
4274*e5337592SStefano Zampini       orntNew[5] = -4;
4275*e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
4276*e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
4277*e5337592SStefano Zampini #if 1
4278*e5337592SStefano Zampini       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);
4279*e5337592SStefano Zampini       for (p = 0; p < 6; ++p) {
4280*e5337592SStefano Zampini         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);
4281*e5337592SStefano Zampini       }
4282*e5337592SStefano Zampini #endif
4283*e5337592SStefano Zampini       /* D hex */
4284*e5337592SStefano Zampini       coneNew[0] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 3;               /* B */
4285*e5337592SStefano Zampini       orntNew[0] = 0;
4286*e5337592SStefano Zampini       coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */
4287*e5337592SStefano Zampini       orntNew[1] = ornt[3] < 0 ? -1 : 1;
4288*e5337592SStefano Zampini       coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */
4289*e5337592SStefano Zampini       orntNew[2] = ornt[2] < 0 ? -4 : 2;
4290*e5337592SStefano Zampini       coneNew[3] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 4;               /* K */
4291*e5337592SStefano Zampini       orntNew[3] = -1;
4292*e5337592SStefano Zampini       coneNew[4] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 5;               /* R */
4293*e5337592SStefano Zampini       orntNew[4] = 0;
4294*e5337592SStefano Zampini       coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */
4295*e5337592SStefano Zampini       orntNew[5] = ornt[1] < 0 ? -2 : 0;
4296*e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
4297*e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
4298*e5337592SStefano Zampini #if 1
4299*e5337592SStefano Zampini       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);
4300*e5337592SStefano Zampini       for (p = 0; p < 6; ++p) {
4301*e5337592SStefano Zampini         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);
4302*e5337592SStefano Zampini       }
4303*e5337592SStefano Zampini #endif
4304*e5337592SStefano Zampini     }
4305*e5337592SStefano Zampini     /* Split faces have 4 edges and the same cells as the parent */
4306*e5337592SStefano Zampini     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
4307*e5337592SStefano Zampini     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
4308*e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
4309*e5337592SStefano Zampini       const PetscInt  newp = fStartNew + (f - fStart)*3;
4310*e5337592SStefano Zampini       const PetscInt *cone, *ornt, *support;
4311*e5337592SStefano Zampini       PetscInt        coneNew[4], orntNew[4], coneSize, supportSize, s;
4312*e5337592SStefano Zampini 
4313*e5337592SStefano Zampini       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
4314*e5337592SStefano Zampini       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
4315*e5337592SStefano Zampini       /* A quad */
4316*e5337592SStefano Zampini       coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
4317*e5337592SStefano Zampini       orntNew[0] = ornt[2];
4318*e5337592SStefano Zampini       coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
4319*e5337592SStefano Zampini       orntNew[1] = ornt[0];
4320*e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
4321*e5337592SStefano Zampini       orntNew[2] = 0;
4322*e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
4323*e5337592SStefano Zampini       orntNew[3] = -2;
4324*e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
4325*e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
4326*e5337592SStefano Zampini #if 1
4327*e5337592SStefano Zampini       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);
4328*e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4329*e5337592SStefano Zampini         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);
4330*e5337592SStefano Zampini       }
4331*e5337592SStefano Zampini #endif
4332*e5337592SStefano Zampini       /* B quad */
4333*e5337592SStefano Zampini       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
4334*e5337592SStefano Zampini       orntNew[0] = ornt[0];
4335*e5337592SStefano Zampini       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
4336*e5337592SStefano Zampini       orntNew[1] = ornt[1];
4337*e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
4338*e5337592SStefano Zampini       orntNew[2] = 0;
4339*e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
4340*e5337592SStefano Zampini       orntNew[3] = -2;
4341*e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
4342*e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
4343*e5337592SStefano Zampini #if 1
4344*e5337592SStefano Zampini       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);
4345*e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4346*e5337592SStefano Zampini         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);
4347*e5337592SStefano Zampini       }
4348*e5337592SStefano Zampini #endif
4349*e5337592SStefano Zampini       /* C quad */
4350*e5337592SStefano Zampini       coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
4351*e5337592SStefano Zampini       orntNew[0] = ornt[1];
4352*e5337592SStefano Zampini       coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
4353*e5337592SStefano Zampini       orntNew[1] = ornt[2];
4354*e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
4355*e5337592SStefano Zampini       orntNew[2] = 0;
4356*e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
4357*e5337592SStefano Zampini       orntNew[3] = -2;
4358*e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
4359*e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
4360*e5337592SStefano Zampini #if 1
4361*e5337592SStefano Zampini       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);
4362*e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4363*e5337592SStefano Zampini         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);
4364*e5337592SStefano Zampini       }
4365*e5337592SStefano Zampini #endif
4366*e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
4367*e5337592SStefano Zampini       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
4368*e5337592SStefano Zampini       for (r = 0; r < 3; ++r) {
4369*e5337592SStefano Zampini         for (s = 0; s < supportSize; ++s) {
4370*e5337592SStefano Zampini           PetscInt subf;
4371*e5337592SStefano Zampini           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
4372*e5337592SStefano Zampini           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4373*e5337592SStefano Zampini           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
4374*e5337592SStefano Zampini           for (c = 0; c < coneSize; ++c) {
4375*e5337592SStefano Zampini             if (cone[c] == f) break;
4376*e5337592SStefano Zampini           }
4377*e5337592SStefano Zampini           subf = GetTriSubfaceInverse_Static(ornt[c], r);
4378*e5337592SStefano Zampini           supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf];
4379*e5337592SStefano Zampini         }
4380*e5337592SStefano Zampini         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
4381*e5337592SStefano Zampini #if 1
4382*e5337592SStefano Zampini         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);
4383*e5337592SStefano Zampini         for (p = 0; p < supportSize; ++p) {
4384*e5337592SStefano Zampini           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);
4385*e5337592SStefano Zampini         }
4386*e5337592SStefano Zampini #endif
4387*e5337592SStefano Zampini       }
4388*e5337592SStefano Zampini     }
4389*e5337592SStefano Zampini     /* Interior faces have 4 edges and 2 cells */
4390*e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
4391*e5337592SStefano Zampini       PetscInt        newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6;
4392*e5337592SStefano Zampini       const PetscInt *cone, *ornt;
4393*e5337592SStefano Zampini       PetscInt        coneNew[4], orntNew[4];
4394*e5337592SStefano Zampini       PetscInt        supportNew[2];
4395*e5337592SStefano Zampini 
4396*e5337592SStefano Zampini       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
4397*e5337592SStefano Zampini       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
4398*e5337592SStefano Zampini       /* Face {a, g, m, h} */
4399*e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0);
4400*e5337592SStefano Zampini       orntNew[0] = 0;
4401*e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
4402*e5337592SStefano Zampini       orntNew[1] = 0;
4403*e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
4404*e5337592SStefano Zampini       orntNew[2] = -2;
4405*e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2);
4406*e5337592SStefano Zampini       orntNew[3] = -2;
4407*e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4408*e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4409*e5337592SStefano Zampini #if 1
4410*e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4411*e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4412*e5337592SStefano Zampini         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);
4413*e5337592SStefano Zampini       }
4414*e5337592SStefano Zampini #endif
4415*e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 0;
4416*e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 1;
4417*e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4418*e5337592SStefano Zampini #if 1
4419*e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4420*e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4421*e5337592SStefano Zampini         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);
4422*e5337592SStefano Zampini       }
4423*e5337592SStefano Zampini #endif
4424*e5337592SStefano Zampini       ++newp;
4425*e5337592SStefano Zampini       /* Face {g, b, l , m} */
4426*e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1);
4427*e5337592SStefano Zampini       orntNew[0] = -2;
4428*e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0);
4429*e5337592SStefano Zampini       orntNew[1] = 0;
4430*e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
4431*e5337592SStefano Zampini       orntNew[2] = 0;
4432*e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
4433*e5337592SStefano Zampini       orntNew[3] = -2;
4434*e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4435*e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4436*e5337592SStefano Zampini #if 1
4437*e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4438*e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4439*e5337592SStefano Zampini         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);
4440*e5337592SStefano Zampini       }
4441*e5337592SStefano Zampini #endif
4442*e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 1;
4443*e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 2;
4444*e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4445*e5337592SStefano Zampini #if 1
4446*e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4447*e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4448*e5337592SStefano Zampini         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);
4449*e5337592SStefano Zampini       }
4450*e5337592SStefano Zampini #endif
4451*e5337592SStefano Zampini       ++newp;
4452*e5337592SStefano Zampini       /* Face {c, g, m, i} */
4453*e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2);
4454*e5337592SStefano Zampini       orntNew[0] = 0;
4455*e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
4456*e5337592SStefano Zampini       orntNew[1] = 0;
4457*e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
4458*e5337592SStefano Zampini       orntNew[2] = -2;
4459*e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0);
4460*e5337592SStefano Zampini       orntNew[3] = -2;
4461*e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4462*e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4463*e5337592SStefano Zampini #if 1
4464*e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4465*e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4466*e5337592SStefano Zampini         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);
4467*e5337592SStefano Zampini       }
4468*e5337592SStefano Zampini #endif
4469*e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 0;
4470*e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 2;
4471*e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4472*e5337592SStefano Zampini #if 1
4473*e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4474*e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4475*e5337592SStefano Zampini         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);
4476*e5337592SStefano Zampini       }
4477*e5337592SStefano Zampini #endif
4478*e5337592SStefano Zampini       ++newp;
4479*e5337592SStefano Zampini       /* Face {d, h, m, i} */
4480*e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0);
4481*e5337592SStefano Zampini       orntNew[0] = 0;
4482*e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
4483*e5337592SStefano Zampini       orntNew[1] = 0;
4484*e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
4485*e5337592SStefano Zampini       orntNew[2] = -2;
4486*e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2);
4487*e5337592SStefano Zampini       orntNew[3] = -2;
4488*e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4489*e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4490*e5337592SStefano Zampini #if 1
4491*e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4492*e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4493*e5337592SStefano Zampini         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);
4494*e5337592SStefano Zampini       }
4495*e5337592SStefano Zampini #endif
4496*e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 0;
4497*e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 3;
4498*e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4499*e5337592SStefano Zampini #if 1
4500*e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4501*e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4502*e5337592SStefano Zampini         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);
4503*e5337592SStefano Zampini       }
4504*e5337592SStefano Zampini #endif
4505*e5337592SStefano Zampini       ++newp;
4506*e5337592SStefano Zampini       /* Face {h, m, l, e} */
4507*e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
4508*e5337592SStefano Zampini       orntNew[0] = 0;
4509*e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
4510*e5337592SStefano Zampini       orntNew[1] = -2;
4511*e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1);
4512*e5337592SStefano Zampini       orntNew[2] = -2;
4513*e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1);
4514*e5337592SStefano Zampini       orntNew[3] = 0;
4515*e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4516*e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4517*e5337592SStefano Zampini #if 1
4518*e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4519*e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4520*e5337592SStefano Zampini         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);
4521*e5337592SStefano Zampini       }
4522*e5337592SStefano Zampini #endif
4523*e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 1;
4524*e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 3;
4525*e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4526*e5337592SStefano Zampini #if 1
4527*e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4528*e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4529*e5337592SStefano Zampini         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);
4530*e5337592SStefano Zampini       }
4531*e5337592SStefano Zampini #endif
4532*e5337592SStefano Zampini       ++newp;
4533*e5337592SStefano Zampini       /* Face {i, m, l, f} */
4534*e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
4535*e5337592SStefano Zampini       orntNew[0] = 0;
4536*e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
4537*e5337592SStefano Zampini       orntNew[1] = -2;
4538*e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2);
4539*e5337592SStefano Zampini       orntNew[2] = -2;
4540*e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1);
4541*e5337592SStefano Zampini       orntNew[3] = 0;
4542*e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4543*e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4544*e5337592SStefano Zampini #if 1
4545*e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4546*e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4547*e5337592SStefano Zampini         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);
4548*e5337592SStefano Zampini       }
4549*e5337592SStefano Zampini #endif
4550*e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 2;
4551*e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 3;
4552*e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4553*e5337592SStefano Zampini #if 1
4554*e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4555*e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4556*e5337592SStefano Zampini         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);
4557*e5337592SStefano Zampini       }
4558*e5337592SStefano Zampini #endif
4559*e5337592SStefano Zampini       ++newp;
4560*e5337592SStefano Zampini     }
4561*e5337592SStefano Zampini     /* Split Edges have 2 vertices and the same faces as the parent */
4562*e5337592SStefano Zampini     for (e = eStart; e < eEnd; ++e) {
4563*e5337592SStefano Zampini       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
4564*e5337592SStefano Zampini 
4565*e5337592SStefano Zampini       for (r = 0; r < 2; ++r) {
4566*e5337592SStefano Zampini         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
4567*e5337592SStefano Zampini         const PetscInt *cone, *ornt, *support;
4568*e5337592SStefano Zampini         PetscInt        coneNew[2], coneSize, c, supportSize, s;
4569*e5337592SStefano Zampini 
4570*e5337592SStefano Zampini         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
4571*e5337592SStefano Zampini         coneNew[0]       = vStartNew + (cone[0] - vStart);
4572*e5337592SStefano Zampini         coneNew[1]       = vStartNew + (cone[1] - vStart);
4573*e5337592SStefano Zampini         coneNew[(r+1)%2] = newv;
4574*e5337592SStefano Zampini         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4575*e5337592SStefano Zampini #if 1
4576*e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4577*e5337592SStefano Zampini         for (p = 0; p < 2; ++p) {
4578*e5337592SStefano Zampini           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);
4579*e5337592SStefano Zampini         }
4580*e5337592SStefano Zampini #endif
4581*e5337592SStefano Zampini         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
4582*e5337592SStefano Zampini         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
4583*e5337592SStefano Zampini         for (s = 0; s < supportSize; ++s) {
4584*e5337592SStefano Zampini           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
4585*e5337592SStefano Zampini           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4586*e5337592SStefano Zampini           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
4587*e5337592SStefano Zampini           for (c = 0; c < coneSize; ++c) {
4588*e5337592SStefano Zampini             if (cone[c] == e) break;
4589*e5337592SStefano Zampini           }
4590*e5337592SStefano Zampini           supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3;
4591*e5337592SStefano Zampini         }
4592*e5337592SStefano Zampini         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4593*e5337592SStefano Zampini #if 1
4594*e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4595*e5337592SStefano Zampini         for (p = 0; p < supportSize; ++p) {
4596*e5337592SStefano Zampini           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);
4597*e5337592SStefano Zampini         }
4598*e5337592SStefano Zampini #endif
4599*e5337592SStefano Zampini       }
4600*e5337592SStefano Zampini     }
4601*e5337592SStefano Zampini     /* Face edges have 2 vertices and 2 + cell faces supports */
4602*e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
4603*e5337592SStefano Zampini       const PetscInt *cone, *ornt, *support;
4604*e5337592SStefano Zampini       PetscInt        coneSize, supportSize, s;
4605*e5337592SStefano Zampini 
4606*e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
4607*e5337592SStefano Zampini       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
4608*e5337592SStefano Zampini       for (r = 0; r < 3; ++r) {
4609*e5337592SStefano Zampini         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
4610*e5337592SStefano Zampini         PetscInt        coneNew[2];
4611*e5337592SStefano Zampini         PetscInt        fint[4][3] = { {0, 1, 2},
4612*e5337592SStefano Zampini                                        {3, 4, 0},
4613*e5337592SStefano Zampini                                        {2, 5, 3},
4614*e5337592SStefano Zampini                                        {1, 4, 5} };
4615*e5337592SStefano Zampini 
4616*e5337592SStefano Zampini         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
4617*e5337592SStefano Zampini         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
4618*e5337592SStefano Zampini         coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart;
4619*e5337592SStefano Zampini         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4620*e5337592SStefano Zampini #if 1
4621*e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4622*e5337592SStefano Zampini         for (p = 0; p < 2; ++p) {
4623*e5337592SStefano Zampini           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);
4624*e5337592SStefano Zampini         }
4625*e5337592SStefano Zampini #endif
4626*e5337592SStefano Zampini         supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3;
4627*e5337592SStefano Zampini         supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3;
4628*e5337592SStefano Zampini         for (s = 0; s < supportSize; ++s) {
4629*e5337592SStefano Zampini           PetscInt er;
4630*e5337592SStefano Zampini           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
4631*e5337592SStefano Zampini           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4632*e5337592SStefano Zampini           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
4633*e5337592SStefano Zampini           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
4634*e5337592SStefano Zampini           er = GetTriInteriorEdgeInverse_Static(ornt[c], r);
4635*e5337592SStefano Zampini           supportRef[2+s] = fStartNew + (fEnd - fStart)*3 + (support[s] - cStart)*6 + fint[c][er];
4636*e5337592SStefano Zampini         }
4637*e5337592SStefano Zampini         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4638*e5337592SStefano Zampini #if 1
4639*e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4640*e5337592SStefano Zampini         for (p = 0; p < supportSize + 2; ++p) {
4641*e5337592SStefano Zampini           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);
4642*e5337592SStefano Zampini         }
4643*e5337592SStefano Zampini #endif
4644*e5337592SStefano Zampini       }
4645*e5337592SStefano Zampini     }
4646*e5337592SStefano Zampini     /* Interior cell edges have 2 vertices and 3 faces */
4647*e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
4648*e5337592SStefano Zampini       const PetscInt *cone;
4649*e5337592SStefano Zampini       PetscInt       fint[4][3] = { {0,1,2},
4650*e5337592SStefano Zampini                                     {0,3,4},
4651*e5337592SStefano Zampini                                     {2,3,5},
4652*e5337592SStefano Zampini                                     {1,4,5} } ;
4653*e5337592SStefano Zampini 
4654*e5337592SStefano Zampini       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
4655*e5337592SStefano Zampini       for (r = 0; r < 4; r++) {
4656*e5337592SStefano Zampini         PetscInt       coneNew[2], supportNew[3];
4657*e5337592SStefano Zampini         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r;
4658*e5337592SStefano Zampini 
4659*e5337592SStefano Zampini         coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
4660*e5337592SStefano Zampini         coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd -fStart) + c - cStart;
4661*e5337592SStefano Zampini         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4662*e5337592SStefano Zampini #if 1
4663*e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4664*e5337592SStefano Zampini         for (p = 0; p < 2; ++p) {
4665*e5337592SStefano Zampini           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);
4666*e5337592SStefano Zampini         }
4667*e5337592SStefano Zampini #endif
4668*e5337592SStefano Zampini         supportNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][0];
4669*e5337592SStefano Zampini         supportNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][1];
4670*e5337592SStefano Zampini         supportNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][2];
4671*e5337592SStefano Zampini         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4672*e5337592SStefano Zampini #if 1
4673*e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4674*e5337592SStefano Zampini         for (p = 0; p < 3; ++p) {
4675*e5337592SStefano Zampini           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);
4676*e5337592SStefano Zampini         }
4677*e5337592SStefano Zampini #endif
4678*e5337592SStefano Zampini       }
4679*e5337592SStefano Zampini     }
4680*e5337592SStefano Zampini     /* Old vertices have identical supports */
4681*e5337592SStefano Zampini     for (v = vStart; v < vEnd; ++v) {
4682*e5337592SStefano Zampini       const PetscInt  newp = vStartNew + (v - vStart);
4683*e5337592SStefano Zampini       const PetscInt *support, *cone;
4684*e5337592SStefano Zampini       PetscInt        size, s;
4685*e5337592SStefano Zampini 
4686*e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
4687*e5337592SStefano Zampini       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
4688*e5337592SStefano Zampini       for (s = 0; s < size; ++s) {
4689*e5337592SStefano Zampini         PetscInt r = 0;
4690*e5337592SStefano Zampini 
4691*e5337592SStefano Zampini         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4692*e5337592SStefano Zampini         if (cone[1] == v) r = 1;
4693*e5337592SStefano Zampini         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
4694*e5337592SStefano Zampini       }
4695*e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4696*e5337592SStefano Zampini #if 1
4697*e5337592SStefano Zampini       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
4698*e5337592SStefano Zampini       for (p = 0; p < size; ++p) {
4699*e5337592SStefano Zampini         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);
4700*e5337592SStefano Zampini       }
4701*e5337592SStefano Zampini #endif
4702*e5337592SStefano Zampini     }
4703*e5337592SStefano Zampini     /* Edge vertices have 2 + faces supports */
4704*e5337592SStefano Zampini     for (e = eStart; e < eEnd; ++e) {
4705*e5337592SStefano Zampini       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
4706*e5337592SStefano Zampini       const PetscInt *cone, *support;
4707*e5337592SStefano Zampini       PetscInt        size, s;
4708*e5337592SStefano Zampini 
4709*e5337592SStefano Zampini       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
4710*e5337592SStefano Zampini       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
4711*e5337592SStefano Zampini       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
4712*e5337592SStefano Zampini       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
4713*e5337592SStefano Zampini       for (s = 0; s < size; ++s) {
4714*e5337592SStefano Zampini         PetscInt r = 0, coneSize;
4715*e5337592SStefano Zampini 
4716*e5337592SStefano Zampini         ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
4717*e5337592SStefano Zampini         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4718*e5337592SStefano Zampini         for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
4719*e5337592SStefano Zampini         supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + r;
4720*e5337592SStefano Zampini       }
4721*e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4722*e5337592SStefano Zampini #if 1
4723*e5337592SStefano Zampini       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
4724*e5337592SStefano Zampini       for (p = 0; p < 2+size; ++p) {
4725*e5337592SStefano Zampini         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);
4726*e5337592SStefano Zampini       }
4727*e5337592SStefano Zampini #endif
4728*e5337592SStefano Zampini     }
4729*e5337592SStefano Zampini     /* Face vertices have 3 + cells supports */
4730*e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
4731*e5337592SStefano Zampini       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
4732*e5337592SStefano Zampini       const PetscInt *cone, *support;
4733*e5337592SStefano Zampini       PetscInt        size, s;
4734*e5337592SStefano Zampini 
4735*e5337592SStefano Zampini       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
4736*e5337592SStefano Zampini       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
4737*e5337592SStefano Zampini       supportRef[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0;
4738*e5337592SStefano Zampini       supportRef[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1;
4739*e5337592SStefano Zampini       supportRef[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2;
4740*e5337592SStefano Zampini       for (s = 0; s < size; ++s) {
4741*e5337592SStefano Zampini         PetscInt r = 0, coneSize;
4742*e5337592SStefano Zampini 
4743*e5337592SStefano Zampini         ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
4744*e5337592SStefano Zampini         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4745*e5337592SStefano Zampini         for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;}
4746*e5337592SStefano Zampini         supportRef[3+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (support[s] - cStart)*4 + r;
4747*e5337592SStefano Zampini       }
4748*e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4749*e5337592SStefano Zampini #if 1
4750*e5337592SStefano Zampini       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
4751*e5337592SStefano Zampini       for (p = 0; p < 3+size; ++p) {
4752*e5337592SStefano Zampini         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);
4753*e5337592SStefano Zampini       }
4754*e5337592SStefano Zampini #endif
4755*e5337592SStefano Zampini     }
4756*e5337592SStefano Zampini     /* Interior cell vertices have 4 supports */
4757*e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
4758*e5337592SStefano Zampini       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + c - cStart;
4759*e5337592SStefano Zampini       supportRef[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
4760*e5337592SStefano Zampini       supportRef[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
4761*e5337592SStefano Zampini       supportRef[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
4762*e5337592SStefano Zampini       supportRef[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
4763*e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4764*e5337592SStefano Zampini #if 1
4765*e5337592SStefano Zampini       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
4766*e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4767*e5337592SStefano Zampini         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);
4768*e5337592SStefano Zampini       }
4769*e5337592SStefano Zampini #endif
4770*e5337592SStefano Zampini     }
4771*e5337592SStefano Zampini     ierr = PetscFree(supportRef);CHKERRQ(ierr);
4772*e5337592SStefano Zampini     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
4773*e5337592SStefano Zampini     break;
47749b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
47752eabf88fSMatthew G. Knepley     /*
47762eabf88fSMatthew G. Knepley      Bottom (viewed from top)    Top
47772eabf88fSMatthew G. Knepley      1---------2---------2       7---------2---------6
47782eabf88fSMatthew G. Knepley      |         |         |       |         |         |
47792eabf88fSMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
47802eabf88fSMatthew G. Knepley      |         |         |       |         |         |
47812eabf88fSMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
47822eabf88fSMatthew G. Knepley      |         |         |       |         |         |
47832eabf88fSMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
47842eabf88fSMatthew G. Knepley      |         |         |       |         |         |
47852eabf88fSMatthew G. Knepley      0---------0---------3       4---------0---------5
47862eabf88fSMatthew G. Knepley      */
47872eabf88fSMatthew G. Knepley     /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
47882eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
47892eabf88fSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
47902eabf88fSMatthew G. Knepley       const PetscInt *cone, *ornt;
47912eabf88fSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
47922eabf88fSMatthew G. Knepley 
47932eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
47942eabf88fSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
47952eabf88fSMatthew G. Knepley       /* A hex */
4796e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
47972eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
47982eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
47992eabf88fSMatthew G. Knepley       orntNew[1] = 0;
4800e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
48012eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
48022eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
48032eabf88fSMatthew G. Knepley       orntNew[3] = 0;
48042eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
48052eabf88fSMatthew G. Knepley       orntNew[4] = 0;
4806e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
48072eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
48082eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
48092eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
48102eabf88fSMatthew G. Knepley #if 1
48112eabf88fSMatthew 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);
48122eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
48132eabf88fSMatthew 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);
48142eabf88fSMatthew G. Knepley       }
48152eabf88fSMatthew G. Knepley #endif
48162eabf88fSMatthew G. Knepley       /* B hex */
4817e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
48182eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
48192eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
48202eabf88fSMatthew G. Knepley       orntNew[1] = 0;
48212eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
4822a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
4823e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
48242eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
48252eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
48262eabf88fSMatthew G. Knepley       orntNew[4] = 0;
4827e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
48282eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
48292eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
48302eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
48312eabf88fSMatthew G. Knepley #if 1
48322eabf88fSMatthew 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);
48332eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
48342eabf88fSMatthew 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);
48352eabf88fSMatthew G. Knepley       }
48362eabf88fSMatthew G. Knepley #endif
48372eabf88fSMatthew G. Knepley       /* C hex */
4838e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
48392eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
48402eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
48412eabf88fSMatthew G. Knepley       orntNew[1] = 0;
48422eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
4843a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
4844e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
48452eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
4846e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
48472eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
48482eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
4849a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
48502eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
48512eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
48522eabf88fSMatthew G. Knepley #if 1
48532eabf88fSMatthew 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);
48542eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
48552eabf88fSMatthew 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);
48562eabf88fSMatthew G. Knepley       }
48572eabf88fSMatthew G. Knepley #endif
48582eabf88fSMatthew G. Knepley       /* D hex */
4859e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
48602eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
48612eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
48622eabf88fSMatthew G. Knepley       orntNew[1] = 0;
4863e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
48642eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
48652eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
4866a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4867e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
48682eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
48692eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
4870a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
48712eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
48722eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
48732eabf88fSMatthew G. Knepley #if 1
48742eabf88fSMatthew 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);
48752eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
48762eabf88fSMatthew 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);
48772eabf88fSMatthew G. Knepley       }
48782eabf88fSMatthew G. Knepley #endif
48792eabf88fSMatthew G. Knepley       /* E hex */
48802eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
4881a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
4882e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
48832eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
4884e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
48852eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
48862eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
48872eabf88fSMatthew G. Knepley       orntNew[3] = 0;
48882eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
4889a3cddbf8SMatthew G. Knepley       orntNew[4] = -1;
4890e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
48912eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
4892b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
4893b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
48942eabf88fSMatthew G. Knepley #if 1
4895b164cbf2SMatthew 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);
48962eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
48972eabf88fSMatthew 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);
48982eabf88fSMatthew G. Knepley       }
48992eabf88fSMatthew G. Knepley #endif
49002eabf88fSMatthew G. Knepley       /* F hex */
49012eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
4902a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
4903e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
49042eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
4905e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
49062eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
49072eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
4908a3cddbf8SMatthew G. Knepley       orntNew[3] = -1;
4909e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
49102eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
49112eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
4912a3cddbf8SMatthew G. Knepley       orntNew[5] = 1;
4913b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
4914b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
49152eabf88fSMatthew G. Knepley #if 1
4916b164cbf2SMatthew 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);
49172eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
49182eabf88fSMatthew 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);
49192eabf88fSMatthew G. Knepley       }
49202eabf88fSMatthew G. Knepley #endif
49212eabf88fSMatthew G. Knepley       /* G hex */
49222eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
4923a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
4924e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
49252eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
49262eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
4927a3cddbf8SMatthew G. Knepley       orntNew[2] = 0;
4928e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
49292eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
4930e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
49312eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
49322eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
4933a3cddbf8SMatthew G. Knepley       orntNew[5] = -3;
4934b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
4935b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
49362eabf88fSMatthew G. Knepley #if 1
4937b164cbf2SMatthew 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);
49382eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
49392eabf88fSMatthew 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);
49402eabf88fSMatthew G. Knepley       }
49412eabf88fSMatthew G. Knepley #endif
49422eabf88fSMatthew G. Knepley       /* H hex */
49432eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
4944a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
4945e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
49462eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
49472eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
4948a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
4949e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
49502eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
49512eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
4952a3cddbf8SMatthew G. Knepley       orntNew[4] = 3;
4953e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
49542eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
4955b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
4956b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
49572eabf88fSMatthew G. Knepley #if 1
4958b164cbf2SMatthew 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);
49592eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
49602eabf88fSMatthew 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);
49612eabf88fSMatthew G. Knepley       }
49622eabf88fSMatthew G. Knepley #endif
49632eabf88fSMatthew G. Knepley     }
49642eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
49652eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
4966854ce69bSBarry Smith     ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
49672eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
49682eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
4969aaebbb9dSMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
49702eabf88fSMatthew 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};
49712eabf88fSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
49722eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
4973aaebbb9dSMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
49742eabf88fSMatthew G. Knepley 
49752eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
4976aaebbb9dSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
4977a3cddbf8SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
4978a3cddbf8SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
4979a3cddbf8SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
4980a3cddbf8SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
4981a3cddbf8SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
4982a3cddbf8SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
4983a3cddbf8SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4;
4984a3cddbf8SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
49852eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4986aaebbb9dSMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
49872eabf88fSMatthew G. Knepley #if 1
49882eabf88fSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
49892eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
49902eabf88fSMatthew 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);
49912eabf88fSMatthew G. Knepley         }
49922eabf88fSMatthew G. Knepley #endif
49932eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
49942eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
49952eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
49962eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
49972eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
49982eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
49992eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
50002eabf88fSMatthew G. Knepley             if (cone[c] == f) break;
50012eabf88fSMatthew G. Knepley           }
5002a3cddbf8SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)];
50032eabf88fSMatthew G. Knepley         }
50042eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
50052eabf88fSMatthew G. Knepley #if 1
50062eabf88fSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
50072eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
50082eabf88fSMatthew 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);
50092eabf88fSMatthew G. Knepley         }
50102eabf88fSMatthew G. Knepley #endif
50112eabf88fSMatthew G. Knepley       }
50122eabf88fSMatthew G. Knepley     }
50132eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
50142eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
50152eabf88fSMatthew 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};
5016afb2665bSMatthew G. Knepley       const PetscInt *cone, *ornt;
5017afb2665bSMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
50182eabf88fSMatthew G. Knepley 
50192eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
5020afb2665bSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
5021afb2665bSMatthew G. Knepley       /* A-D face */
5022afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0;
5023a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
5024a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
5025a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
5026afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5027a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
5028a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
5029a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
5030afb2665bSMatthew G. Knepley       orntNew[3] = -2;
50312eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5032afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
50332eabf88fSMatthew G. Knepley #if 1
50342eabf88fSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
50352eabf88fSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
50362eabf88fSMatthew 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);
50372eabf88fSMatthew G. Knepley       }
50382eabf88fSMatthew G. Knepley #endif
5039afb2665bSMatthew G. Knepley       /* C-D face */
5040afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1;
5041a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
5042a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
5043a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
5044afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5045a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
5046a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
5047a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
5048afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5049afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5050afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5051afb2665bSMatthew G. Knepley #if 1
5052afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5053afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5054afb2665bSMatthew 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);
5055afb2665bSMatthew G. Knepley       }
5056afb2665bSMatthew G. Knepley #endif
5057afb2665bSMatthew G. Knepley       /* B-C face */
5058afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2;
5059afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
5060afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5061afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
5062afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5063afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
5064afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5065afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
5066afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5067afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5068afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5069afb2665bSMatthew G. Knepley #if 1
5070afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5071afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5072afb2665bSMatthew 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);
5073afb2665bSMatthew G. Knepley       }
5074afb2665bSMatthew G. Knepley #endif
5075afb2665bSMatthew G. Knepley       /* A-B face */
5076afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3;
5077afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
5078afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5079afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
5080afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5081afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
5082afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5083afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
5084afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5085afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5086afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5087afb2665bSMatthew G. Knepley #if 1
5088afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5089afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5090afb2665bSMatthew 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);
5091afb2665bSMatthew G. Knepley       }
5092afb2665bSMatthew G. Knepley #endif
5093afb2665bSMatthew G. Knepley       /* E-F face */
5094afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4;
5095a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
5096afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5097a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
5098a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
5099a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
5100afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5101a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
5102a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
5103afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5104afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5105afb2665bSMatthew G. Knepley #if 1
5106afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5107afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5108afb2665bSMatthew 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);
5109afb2665bSMatthew G. Knepley       }
5110afb2665bSMatthew G. Knepley #endif
5111afb2665bSMatthew G. Knepley       /* F-G face */
5112afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5;
5113a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
5114afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5115a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
5116a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
5117a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
5118afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5119a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
5120a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
5121afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5122afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5123afb2665bSMatthew G. Knepley #if 1
5124afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5125afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5126afb2665bSMatthew 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);
5127afb2665bSMatthew G. Knepley       }
5128afb2665bSMatthew G. Knepley #endif
5129afb2665bSMatthew G. Knepley       /* G-H face */
5130afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6;
5131afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
5132afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5133afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
5134afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5135afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
5136afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5137afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
5138afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5139afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5140afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5141afb2665bSMatthew G. Knepley #if 1
5142afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5143afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5144afb2665bSMatthew 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);
5145afb2665bSMatthew G. Knepley       }
5146afb2665bSMatthew G. Knepley #endif
5147afb2665bSMatthew G. Knepley       /* E-H face */
5148afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7;
5149a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
5150afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5151a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
5152a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
5153a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
5154afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5155a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
5156a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
5157afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5158afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5159afb2665bSMatthew G. Knepley #if 1
5160afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5161afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5162afb2665bSMatthew 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);
5163afb2665bSMatthew G. Knepley       }
5164afb2665bSMatthew G. Knepley #endif
5165afb2665bSMatthew G. Knepley       /* A-E face */
5166afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8;
5167a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
5168a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
5169a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
5170afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5171a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
5172a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
5173a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
5174afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5175afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5176afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5177afb2665bSMatthew G. Knepley #if 1
5178afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5179afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5180afb2665bSMatthew 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);
5181afb2665bSMatthew G. Knepley       }
5182afb2665bSMatthew G. Knepley #endif
5183afb2665bSMatthew G. Knepley       /* D-F face */
5184afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9;
5185afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
5186afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5187afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
5188afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5189afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
5190afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5191afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
5192afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5193afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5194afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5195afb2665bSMatthew G. Knepley #if 1
5196afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5197afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5198afb2665bSMatthew 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);
5199afb2665bSMatthew G. Knepley       }
5200afb2665bSMatthew G. Knepley #endif
5201afb2665bSMatthew G. Knepley       /* C-G face */
5202afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10;
5203a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
5204afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5205a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
5206a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
5207a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
5208afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5209a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
5210a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
5211afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5212afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5213afb2665bSMatthew G. Knepley #if 1
5214afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5215afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5216afb2665bSMatthew 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);
5217afb2665bSMatthew G. Knepley       }
5218afb2665bSMatthew G. Knepley #endif
5219afb2665bSMatthew G. Knepley       /* B-H face */
5220afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11;
5221a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
5222a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
5223a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
5224a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
5225a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
5226a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
5227a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
5228a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
5229afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5230afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5231afb2665bSMatthew G. Knepley #if 1
5232afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5233afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5234afb2665bSMatthew 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);
5235afb2665bSMatthew G. Knepley       }
5236afb2665bSMatthew G. Knepley #endif
5237afb2665bSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
5238afb2665bSMatthew G. Knepley         newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
52392eabf88fSMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
52402eabf88fSMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
52412eabf88fSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
52422eabf88fSMatthew G. Knepley #if 1
52432eabf88fSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
52442eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
52452eabf88fSMatthew 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);
52462eabf88fSMatthew G. Knepley         }
52472eabf88fSMatthew G. Knepley #endif
52482eabf88fSMatthew G. Knepley       }
52492eabf88fSMatthew G. Knepley     }
52502eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
52512eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
52522eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
52532eabf88fSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
52542eabf88fSMatthew G. Knepley 
52552eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
52562eabf88fSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
52572eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
52582eabf88fSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
52592eabf88fSMatthew G. Knepley 
52602eabf88fSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
52612eabf88fSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
52622eabf88fSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
52632eabf88fSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
52642eabf88fSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
52652eabf88fSMatthew G. Knepley #if 1
52662eabf88fSMatthew 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);
52672eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
52682eabf88fSMatthew 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);
52692eabf88fSMatthew G. Knepley         }
52702eabf88fSMatthew G. Knepley #endif
52712eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
52722eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
52732eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
52742eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
52752eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
52762eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
52772eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
52782eabf88fSMatthew G. Knepley             if (cone[c] == e) break;
52792eabf88fSMatthew G. Knepley           }
52802eabf88fSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
52812eabf88fSMatthew G. Knepley         }
52822eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
52832eabf88fSMatthew G. Knepley #if 1
52842eabf88fSMatthew 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);
52852eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
52862eabf88fSMatthew 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);
52872eabf88fSMatthew G. Knepley         }
52882eabf88fSMatthew G. Knepley #endif
52892eabf88fSMatthew G. Knepley       }
52902eabf88fSMatthew G. Knepley     }
52912eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
52922eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
52936b852384SMatthew 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};
52942eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
52956b852384SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
52962eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
52972eabf88fSMatthew G. Knepley 
52982eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
52992eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
53002eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
53012eabf88fSMatthew G. Knepley 
53022eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
53032eabf88fSMatthew G. Knepley         coneNew[1] = newv;
53042eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
53052eabf88fSMatthew G. Knepley #if 1
53062eabf88fSMatthew 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);
53072eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
53082eabf88fSMatthew 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);
53092eabf88fSMatthew G. Knepley         }
53102eabf88fSMatthew G. Knepley #endif
53112eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
53122eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
53132eabf88fSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
53142eabf88fSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
53152eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
53166b852384SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
53176b852384SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
53186b852384SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
53192eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
5320a3cddbf8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
53212eabf88fSMatthew G. Knepley         }
53222eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
53232eabf88fSMatthew G. Knepley #if 1
53242eabf88fSMatthew 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);
53252eabf88fSMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
53262eabf88fSMatthew 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);
53272eabf88fSMatthew G. Knepley         }
53282eabf88fSMatthew G. Knepley #endif
53292eabf88fSMatthew G. Knepley       }
53302eabf88fSMatthew G. Knepley     }
53312eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
53322eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
53332eabf88fSMatthew 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};
53342eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
53352eabf88fSMatthew G. Knepley       const PetscInt *cone;
53362eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
53372eabf88fSMatthew G. Knepley 
53382eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
53392eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
53402eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
53412eabf88fSMatthew G. Knepley 
53422eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
53432eabf88fSMatthew G. Knepley         coneNew[1] = newv;
53442eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
53452eabf88fSMatthew G. Knepley #if 1
53462eabf88fSMatthew 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);
53472eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
53482eabf88fSMatthew 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);
53492eabf88fSMatthew G. Knepley         }
53502eabf88fSMatthew G. Knepley #endif
53512eabf88fSMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
53522eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
53532eabf88fSMatthew G. Knepley #if 1
53542eabf88fSMatthew 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);
53552eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
53562eabf88fSMatthew 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);
53572eabf88fSMatthew G. Knepley         }
53582eabf88fSMatthew G. Knepley #endif
53592eabf88fSMatthew G. Knepley       }
53602eabf88fSMatthew G. Knepley     }
53612eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
53622eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
53632eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
53642eabf88fSMatthew G. Knepley       const PetscInt *support, *cone;
53652eabf88fSMatthew G. Knepley       PetscInt        size, s;
53662eabf88fSMatthew G. Knepley 
53672eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
53682eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
53692eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
53702eabf88fSMatthew G. Knepley         PetscInt r = 0;
53712eabf88fSMatthew G. Knepley 
53722eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
53732eabf88fSMatthew G. Knepley         if (cone[1] == v) r = 1;
53742eabf88fSMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
53752eabf88fSMatthew G. Knepley       }
53762eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
53772eabf88fSMatthew G. Knepley #if 1
53782eabf88fSMatthew 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);
53792eabf88fSMatthew G. Knepley       for (p = 0; p < size; ++p) {
53802eabf88fSMatthew 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);
53812eabf88fSMatthew G. Knepley       }
53822eabf88fSMatthew G. Knepley #endif
53832eabf88fSMatthew G. Knepley     }
53842eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
53852eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
53862eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
53872eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
53882eabf88fSMatthew G. Knepley       PetscInt        size, s;
53892eabf88fSMatthew G. Knepley 
53902eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
53912eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
53922eabf88fSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
53932eabf88fSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
53942eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
53952eabf88fSMatthew G. Knepley         PetscInt r;
53962eabf88fSMatthew G. Knepley 
53972eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
5398a660e16cSMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
53992eabf88fSMatthew G. Knepley         supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r;
54002eabf88fSMatthew G. Knepley       }
54012eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
54022eabf88fSMatthew G. Knepley #if 1
54032eabf88fSMatthew 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);
54042eabf88fSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
54052eabf88fSMatthew 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);
54062eabf88fSMatthew G. Knepley       }
54072eabf88fSMatthew G. Knepley #endif
54082eabf88fSMatthew G. Knepley     }
54092eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
54102eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
54112eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
54122eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
54132eabf88fSMatthew G. Knepley       PetscInt        size, s;
54142eabf88fSMatthew G. Knepley 
54152eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
54162eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
54170793999aSMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 +  (f - fStart)*4 + r;
54182eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
54192eabf88fSMatthew G. Knepley         PetscInt r;
54202eabf88fSMatthew G. Knepley 
54212eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
54222eabf88fSMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
54232eabf88fSMatthew G. Knepley         supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r;
54242eabf88fSMatthew G. Knepley       }
54252eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
54262eabf88fSMatthew G. Knepley #if 1
54272eabf88fSMatthew 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);
54282eabf88fSMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
54292eabf88fSMatthew 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);
54302eabf88fSMatthew G. Knepley       }
54312eabf88fSMatthew G. Knepley #endif
54322eabf88fSMatthew G. Knepley     }
54332eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
54342eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
54352eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
54362eabf88fSMatthew G. Knepley       PetscInt       supportNew[6];
54372eabf88fSMatthew G. Knepley 
54382eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
54392eabf88fSMatthew G. Knepley         supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
54402eabf88fSMatthew G. Knepley       }
54412eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
54422eabf88fSMatthew G. Knepley     }
5443da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
54442eabf88fSMatthew G. Knepley     break;
54459b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
544627fcede3SMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
544727fcede3SMatthew G. Knepley     /*
544827fcede3SMatthew G. Knepley      Bottom (viewed from top)    Top
544927fcede3SMatthew G. Knepley      1---------2---------2       7---------2---------6
545027fcede3SMatthew G. Knepley      |         |         |       |         |         |
545127fcede3SMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
545227fcede3SMatthew G. Knepley      |         |         |       |         |         |
545327fcede3SMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
545427fcede3SMatthew G. Knepley      |         |         |       |         |         |
545527fcede3SMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
545627fcede3SMatthew G. Knepley      |         |         |       |         |         |
545727fcede3SMatthew G. Knepley      0---------0---------3       4---------0---------5
545827fcede3SMatthew G. Knepley      */
545927fcede3SMatthew G. Knepley     /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
546027fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
546127fcede3SMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
546227fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
546327fcede3SMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
546427fcede3SMatthew G. Knepley 
546527fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
546627fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
546727fcede3SMatthew G. Knepley       /* A hex */
546827fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
546927fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
547027fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
547127fcede3SMatthew G. Knepley       orntNew[1] = 0;
547227fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
547327fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
547427fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
547527fcede3SMatthew G. Knepley       orntNew[3] = 0;
547627fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
547727fcede3SMatthew G. Knepley       orntNew[4] = 0;
547827fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
547927fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
548027fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
548127fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
548227fcede3SMatthew G. Knepley #if 1
548327fcede3SMatthew 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);
548427fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
548527fcede3SMatthew 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);
548627fcede3SMatthew G. Knepley       }
548727fcede3SMatthew G. Knepley #endif
548827fcede3SMatthew G. Knepley       /* B hex */
548927fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
549027fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
549127fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
549227fcede3SMatthew G. Knepley       orntNew[1] = 0;
549327fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
549427fcede3SMatthew G. Knepley       orntNew[2] = -1;
549527fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
549627fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
549727fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
549827fcede3SMatthew G. Knepley       orntNew[4] = 0;
549927fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
550027fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
550127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
550227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
550327fcede3SMatthew G. Knepley #if 1
550427fcede3SMatthew 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);
550527fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
550627fcede3SMatthew 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);
550727fcede3SMatthew G. Knepley       }
550827fcede3SMatthew G. Knepley #endif
550927fcede3SMatthew G. Knepley       /* C hex */
551027fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
551127fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
551227fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
551327fcede3SMatthew G. Knepley       orntNew[1] = 0;
551427fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
551527fcede3SMatthew G. Knepley       orntNew[2] = -1;
551627fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
551727fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
551827fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
551927fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
552027fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
552127fcede3SMatthew G. Knepley       orntNew[5] = -4;
552227fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
552327fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
552427fcede3SMatthew G. Knepley #if 1
552527fcede3SMatthew 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);
552627fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
552727fcede3SMatthew 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);
552827fcede3SMatthew G. Knepley       }
552927fcede3SMatthew G. Knepley #endif
553027fcede3SMatthew G. Knepley       /* D hex */
553127fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
553227fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
553327fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
553427fcede3SMatthew G. Knepley       orntNew[1] = 0;
553527fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
553627fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
553727fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
553827fcede3SMatthew G. Knepley       orntNew[3] = 0;
553927fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
554027fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
554127fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
554227fcede3SMatthew G. Knepley       orntNew[5] = -4;
554327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
554427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
554527fcede3SMatthew G. Knepley #if 1
554627fcede3SMatthew 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);
554727fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
554827fcede3SMatthew 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);
554927fcede3SMatthew G. Knepley       }
555027fcede3SMatthew G. Knepley #endif
555127fcede3SMatthew G. Knepley       /* E hex */
555227fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
555327fcede3SMatthew G. Knepley       orntNew[0] = -4;
555427fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
555527fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
555627fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
555727fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
555827fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
555927fcede3SMatthew G. Knepley       orntNew[3] = 0;
556027fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
556127fcede3SMatthew G. Knepley       orntNew[4] = -1;
556227fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
556327fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
556427fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
556527fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
556627fcede3SMatthew G. Knepley #if 1
556727fcede3SMatthew 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);
556827fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
556927fcede3SMatthew 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);
557027fcede3SMatthew G. Knepley       }
557127fcede3SMatthew G. Knepley #endif
557227fcede3SMatthew G. Knepley       /* F hex */
557327fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
557427fcede3SMatthew G. Knepley       orntNew[0] = -4;
557527fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
557627fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
557727fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
557827fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
557927fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
558027fcede3SMatthew G. Knepley       orntNew[3] = -1;
558127fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
558227fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
558327fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
558427fcede3SMatthew G. Knepley       orntNew[5] = 1;
558527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
558627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
558727fcede3SMatthew G. Knepley #if 1
558827fcede3SMatthew 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);
558927fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
559027fcede3SMatthew 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);
559127fcede3SMatthew G. Knepley       }
559227fcede3SMatthew G. Knepley #endif
559327fcede3SMatthew G. Knepley       /* G hex */
559427fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
559527fcede3SMatthew G. Knepley       orntNew[0] = -4;
559627fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
559727fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
559827fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
559927fcede3SMatthew G. Knepley       orntNew[2] = 0;
560027fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
560127fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
560227fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
560327fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
560427fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
560527fcede3SMatthew G. Knepley       orntNew[5] = -3;
560627fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
560727fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
560827fcede3SMatthew G. Knepley #if 1
560927fcede3SMatthew 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);
561027fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
561127fcede3SMatthew 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);
561227fcede3SMatthew G. Knepley       }
561327fcede3SMatthew G. Knepley #endif
561427fcede3SMatthew G. Knepley       /* H hex */
561527fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
561627fcede3SMatthew G. Knepley       orntNew[0] = -4;
561727fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
561827fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
561927fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
562027fcede3SMatthew G. Knepley       orntNew[2] = -1;
562127fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
562227fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
562327fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
562427fcede3SMatthew G. Knepley       orntNew[4] = 3;
562527fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
562627fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
562727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
562827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
562927fcede3SMatthew G. Knepley #if 1
563027fcede3SMatthew 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);
563127fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
563227fcede3SMatthew 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);
563327fcede3SMatthew G. Knepley       }
563427fcede3SMatthew G. Knepley #endif
563527fcede3SMatthew G. Knepley     }
563627fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces: Front, Back, Sides */
563727fcede3SMatthew G. Knepley     /*
563827fcede3SMatthew G. Knepley      3---------2---------2
563927fcede3SMatthew G. Knepley      |         |         |
564027fcede3SMatthew G. Knepley      |    D    2    C    |
564127fcede3SMatthew G. Knepley      |         |         |
564227fcede3SMatthew G. Knepley      3----3----0----1----1
564327fcede3SMatthew G. Knepley      |         |         |
564427fcede3SMatthew G. Knepley      |    A    0    B    |
564527fcede3SMatthew G. Knepley      |         |         |
564627fcede3SMatthew G. Knepley      0---------0---------1
564727fcede3SMatthew G. Knepley      */
564827fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
564927fcede3SMatthew G. Knepley       const PetscInt  newp = (cMax - cStart)*8 + (c - cMax)*4;
565027fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
5651d273725eSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6], o, of, i;
565227fcede3SMatthew G. Knepley 
565327fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
565427fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
565527fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
5656d273725eSMatthew G. Knepley       o = ornt[0] < 0 ? -1 : 1;
565727fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
565827fcede3SMatthew G. Knepley         PetscInt subfA = GetQuadSubface_Static(ornt[0], r);
565927fcede3SMatthew G. Knepley         PetscInt edgeA = GetQuadEdge_Static(ornt[0], r);
5660d273725eSMatthew G. Knepley         PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4);
566127fcede3SMatthew 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]);
566227fcede3SMatthew G. Knepley         coneNew[0]         = fStartNew + (cone[0] - fStart)*4 + subfA;
566327fcede3SMatthew G. Knepley         orntNew[0]         = ornt[0];
566427fcede3SMatthew G. Knepley         coneNew[1]         = fStartNew + (cone[1] - fStart)*4 + subfA;
566527fcede3SMatthew G. Knepley         orntNew[1]         = ornt[0];
5666d273725eSMatthew G. Knepley         of = fornt[edgeA] < 0 ? -1 : 1;
5667d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], r) + 2;
5668d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0);
5669d273725eSMatthew G. Knepley         orntNew[i] = ornt[edgeA];
5670d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2;
5671d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeA;
5672d273725eSMatthew G. Knepley         orntNew[i] = 0;
5673d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2;
5674d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeB;
5675d273725eSMatthew G. Knepley         orntNew[i] = -2;
5676d273725eSMatthew G. Knepley         of = fornt[edgeB] < 0 ? -1 : 1;
5677d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2;
5678d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1);
5679d273725eSMatthew G. Knepley         orntNew[i] = ornt[edgeB];
568027fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
568127fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
568227fcede3SMatthew G. Knepley #if 1
568327fcede3SMatthew 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);
568427fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
568527fcede3SMatthew 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);
568627fcede3SMatthew G. Knepley         }
568727fcede3SMatthew G. Knepley         for (p = 2; p < 6; ++p) {
568827fcede3SMatthew 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);
568927fcede3SMatthew G. Knepley         }
569027fcede3SMatthew G. Knepley #endif
569127fcede3SMatthew G. Knepley       }
569227fcede3SMatthew G. Knepley     }
569327fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
569427fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
5695854ce69bSBarry Smith     ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
569627fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
569727fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
569827fcede3SMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
569927fcede3SMatthew 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};
570027fcede3SMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
570127fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
570227fcede3SMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
570327fcede3SMatthew G. Knepley 
570427fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
570527fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
570627fcede3SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
570727fcede3SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
570827fcede3SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
570927fcede3SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
571027fcede3SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
571127fcede3SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
571227fcede3SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4;
571327fcede3SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
571427fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
571527fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
571627fcede3SMatthew G. Knepley #if 1
571727fcede3SMatthew 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);
571827fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
571927fcede3SMatthew 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);
572027fcede3SMatthew G. Knepley         }
572127fcede3SMatthew G. Knepley #endif
572227fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
572327fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
572427fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
572527fcede3SMatthew G. Knepley           PetscInt subf;
572627fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
572727fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
572827fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
572927fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
573027fcede3SMatthew G. Knepley             if (cone[c] == f) break;
573127fcede3SMatthew G. Knepley           }
573227fcede3SMatthew G. Knepley           subf = GetQuadSubfaceInverse_Static(ornt[c], r);
573327fcede3SMatthew G. Knepley           if (support[s] < cMax) {
573427fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf];
573527fcede3SMatthew G. Knepley           } else {
573627fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax       - cStart)*8 + (support[s] - cMax)*4 + subf;
573727fcede3SMatthew G. Knepley           }
573827fcede3SMatthew G. Knepley         }
573927fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
574027fcede3SMatthew G. Knepley #if 1
574127fcede3SMatthew 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);
574227fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
574327fcede3SMatthew 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);
574427fcede3SMatthew G. Knepley         }
574527fcede3SMatthew G. Knepley #endif
574627fcede3SMatthew G. Knepley       }
574727fcede3SMatthew G. Knepley     }
5748d273725eSMatthew G. Knepley     /* Interior cell faces have 4 edges and 2 cells */
574927fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
575027fcede3SMatthew 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};
575127fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
575227fcede3SMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
575327fcede3SMatthew G. Knepley 
575427fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
575527fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
575627fcede3SMatthew G. Knepley       /* A-D face */
575727fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0;
575827fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
575927fcede3SMatthew G. Knepley       orntNew[0] = 0;
576027fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
576127fcede3SMatthew G. Knepley       orntNew[1] = 0;
576227fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
576327fcede3SMatthew G. Knepley       orntNew[2] = -2;
576427fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
576527fcede3SMatthew G. Knepley       orntNew[3] = -2;
576627fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
576727fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
576827fcede3SMatthew G. Knepley #if 1
576927fcede3SMatthew 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);
577027fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
577127fcede3SMatthew 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);
577227fcede3SMatthew G. Knepley       }
577327fcede3SMatthew G. Knepley #endif
577427fcede3SMatthew G. Knepley       /* C-D face */
577527fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1;
577627fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
577727fcede3SMatthew G. Knepley       orntNew[0] = 0;
577827fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
577927fcede3SMatthew G. Knepley       orntNew[1] = 0;
578027fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
578127fcede3SMatthew G. Knepley       orntNew[2] = -2;
578227fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
578327fcede3SMatthew G. Knepley       orntNew[3] = -2;
578427fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
578527fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
578627fcede3SMatthew G. Knepley #if 1
578727fcede3SMatthew 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);
578827fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
578927fcede3SMatthew 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);
579027fcede3SMatthew G. Knepley       }
579127fcede3SMatthew G. Knepley #endif
579227fcede3SMatthew G. Knepley       /* B-C face */
579327fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2;
579427fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
579527fcede3SMatthew G. Knepley       orntNew[0] = -2;
579627fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
579727fcede3SMatthew G. Knepley       orntNew[1] = 0;
579827fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
579927fcede3SMatthew G. Knepley       orntNew[2] = 0;
580027fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
580127fcede3SMatthew G. Knepley       orntNew[3] = -2;
580227fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
580327fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
580427fcede3SMatthew G. Knepley #if 1
580527fcede3SMatthew 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);
580627fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
580727fcede3SMatthew 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);
580827fcede3SMatthew G. Knepley       }
580927fcede3SMatthew G. Knepley #endif
581027fcede3SMatthew G. Knepley       /* A-B face */
581127fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3;
581227fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
581327fcede3SMatthew G. Knepley       orntNew[0] = -2;
581427fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
581527fcede3SMatthew G. Knepley       orntNew[1] = 0;
581627fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
581727fcede3SMatthew G. Knepley       orntNew[2] = 0;
581827fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
581927fcede3SMatthew G. Knepley       orntNew[3] = -2;
582027fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
582127fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
582227fcede3SMatthew G. Knepley #if 1
582327fcede3SMatthew 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);
582427fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
582527fcede3SMatthew 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);
582627fcede3SMatthew G. Knepley       }
582727fcede3SMatthew G. Knepley #endif
582827fcede3SMatthew G. Knepley       /* E-F face */
582927fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4;
583027fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
583127fcede3SMatthew G. Knepley       orntNew[0] = -2;
583227fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
583327fcede3SMatthew G. Knepley       orntNew[1] = -2;
583427fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
583527fcede3SMatthew G. Knepley       orntNew[2] = 0;
583627fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
583727fcede3SMatthew G. Knepley       orntNew[3] = 0;
583827fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
583927fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
584027fcede3SMatthew G. Knepley #if 1
584127fcede3SMatthew 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);
584227fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
584327fcede3SMatthew 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);
584427fcede3SMatthew G. Knepley       }
584527fcede3SMatthew G. Knepley #endif
584627fcede3SMatthew G. Knepley       /* F-G face */
584727fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5;
584827fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
584927fcede3SMatthew G. Knepley       orntNew[0] = -2;
585027fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
585127fcede3SMatthew G. Knepley       orntNew[1] = -2;
585227fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
585327fcede3SMatthew G. Knepley       orntNew[2] = 0;
585427fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
585527fcede3SMatthew G. Knepley       orntNew[3] = 0;
585627fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
585727fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
585827fcede3SMatthew G. Knepley #if 1
585927fcede3SMatthew 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);
586027fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
586127fcede3SMatthew 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);
586227fcede3SMatthew G. Knepley       }
586327fcede3SMatthew G. Knepley #endif
586427fcede3SMatthew G. Knepley       /* G-H face */
586527fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6;
586627fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
586727fcede3SMatthew G. Knepley       orntNew[0] = -2;
586827fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
586927fcede3SMatthew G. Knepley       orntNew[1] = 0;
587027fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
587127fcede3SMatthew G. Knepley       orntNew[2] = 0;
587227fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
587327fcede3SMatthew G. Knepley       orntNew[3] = -2;
587427fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
587527fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
587627fcede3SMatthew G. Knepley #if 1
587727fcede3SMatthew 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);
587827fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
587927fcede3SMatthew 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);
588027fcede3SMatthew G. Knepley       }
588127fcede3SMatthew G. Knepley #endif
588227fcede3SMatthew G. Knepley       /* E-H face */
588327fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7;
588427fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
588527fcede3SMatthew G. Knepley       orntNew[0] = -2;
588627fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
588727fcede3SMatthew G. Knepley       orntNew[1] = -2;
588827fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
588927fcede3SMatthew G. Knepley       orntNew[2] = 0;
589027fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
589127fcede3SMatthew G. Knepley       orntNew[3] = 0;
589227fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
589327fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
589427fcede3SMatthew G. Knepley #if 1
589527fcede3SMatthew 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);
589627fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
589727fcede3SMatthew 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);
589827fcede3SMatthew G. Knepley       }
589927fcede3SMatthew G. Knepley #endif
590027fcede3SMatthew G. Knepley       /* A-E face */
590127fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8;
590227fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
590327fcede3SMatthew G. Knepley       orntNew[0] = 0;
590427fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
590527fcede3SMatthew G. Knepley       orntNew[1] = 0;
590627fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
590727fcede3SMatthew G. Knepley       orntNew[2] = -2;
590827fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
590927fcede3SMatthew G. Knepley       orntNew[3] = -2;
591027fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
591127fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
591227fcede3SMatthew G. Knepley #if 1
591327fcede3SMatthew 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);
591427fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
591527fcede3SMatthew 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);
591627fcede3SMatthew G. Knepley       }
591727fcede3SMatthew G. Knepley #endif
591827fcede3SMatthew G. Knepley       /* D-F face */
591927fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9;
592027fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
592127fcede3SMatthew G. Knepley       orntNew[0] = -2;
592227fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
592327fcede3SMatthew G. Knepley       orntNew[1] = 0;
592427fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
592527fcede3SMatthew G. Knepley       orntNew[2] = 0;
592627fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
592727fcede3SMatthew G. Knepley       orntNew[3] = -2;
592827fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
592927fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
593027fcede3SMatthew G. Knepley #if 1
593127fcede3SMatthew 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);
593227fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
593327fcede3SMatthew 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);
593427fcede3SMatthew G. Knepley       }
593527fcede3SMatthew G. Knepley #endif
593627fcede3SMatthew G. Knepley       /* C-G face */
593727fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10;
593827fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
593927fcede3SMatthew G. Knepley       orntNew[0] = -2;
594027fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
594127fcede3SMatthew G. Knepley       orntNew[1] = -2;
594227fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
594327fcede3SMatthew G. Knepley       orntNew[2] = 0;
594427fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
594527fcede3SMatthew G. Knepley       orntNew[3] = 0;
594627fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
594727fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
594827fcede3SMatthew G. Knepley #if 1
594927fcede3SMatthew 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);
595027fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
595127fcede3SMatthew 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);
595227fcede3SMatthew G. Knepley       }
595327fcede3SMatthew G. Knepley #endif
595427fcede3SMatthew G. Knepley       /* B-H face */
595527fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11;
595627fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
595727fcede3SMatthew G. Knepley       orntNew[0] = 0;
595827fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
595927fcede3SMatthew G. Knepley       orntNew[1] = -2;
596027fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
596127fcede3SMatthew G. Knepley       orntNew[2] = -2;
596227fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
596327fcede3SMatthew G. Knepley       orntNew[3] = 0;
596427fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
596527fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
596627fcede3SMatthew G. Knepley #if 1
596727fcede3SMatthew 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);
596827fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
596927fcede3SMatthew 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);
597027fcede3SMatthew G. Knepley       }
597127fcede3SMatthew G. Knepley #endif
597227fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
597327fcede3SMatthew G. Knepley         newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
597427fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
597527fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
597627fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
597727fcede3SMatthew G. Knepley #if 1
597827fcede3SMatthew 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);
597927fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
598027fcede3SMatthew 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);
598127fcede3SMatthew G. Knepley         }
598227fcede3SMatthew G. Knepley #endif
598327fcede3SMatthew G. Knepley       }
598427fcede3SMatthew G. Knepley     }
598527fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
598627fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
598727fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
598827fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
598927fcede3SMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
599027fcede3SMatthew G. Knepley 
599127fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
599227fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
599327fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
599427fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
599527fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
599627fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
599727fcede3SMatthew G. Knepley 
599827fcede3SMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
599927fcede3SMatthew G. Knepley         orntNew[0]   = ornt[0];
600027fcede3SMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
600127fcede3SMatthew G. Knepley         orntNew[1]   = ornt[1];
600227fcede3SMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax);
600327fcede3SMatthew G. Knepley         orntNew[2+r] = 0;
600427fcede3SMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd      - eMax) + (f - fMax);
600527fcede3SMatthew G. Knepley         orntNew[3-r] = 0;
600627fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
600727fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
600827fcede3SMatthew G. Knepley #if 1
600927fcede3SMatthew 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);
601027fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
601127fcede3SMatthew 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);
601227fcede3SMatthew G. Knepley         }
601327fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
601427fcede3SMatthew 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);
601527fcede3SMatthew G. Knepley         }
601627fcede3SMatthew G. Knepley #endif
601727fcede3SMatthew G. Knepley         for (s = 0; s < size; ++s) {
601827fcede3SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
6019d273725eSMatthew G. Knepley           PetscInt        o, of;
602027fcede3SMatthew G. Knepley 
602127fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
602227fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
6023d273725eSMatthew G. Knepley           o = orntCell[0] < 0 ? -1 : 1;
602427fcede3SMatthew G. Knepley           for (c = 2; c < 6; ++c) if (coneCell[c] == f) break;
602527fcede3SMatthew 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]);
602627fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
6027d273725eSMatthew G. Knepley           of = fornt[c-2] < 0 ? -1 : 1;
6028d273725eSMatthew 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;
602927fcede3SMatthew G. Knepley         }
603027fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
603127fcede3SMatthew G. Knepley #if 1
603227fcede3SMatthew 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);
603327fcede3SMatthew G. Knepley         for (p = 0; p < size; ++p) {
603427fcede3SMatthew 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);
603527fcede3SMatthew G. Knepley         }
603627fcede3SMatthew G. Knepley #endif
603727fcede3SMatthew G. Knepley       }
603827fcede3SMatthew G. Knepley     }
603927fcede3SMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
604027fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
604127fcede3SMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4;
604227fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
604327fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
604427fcede3SMatthew G. Knepley       PetscInt        supportNew[2];
604527fcede3SMatthew G. Knepley 
604627fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
604727fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
604827fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
6049d273725eSMatthew G. Knepley #if 0
605027fcede3SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r);
605127fcede3SMatthew G. Knepley         orntNew[0] = 0;
605227fcede3SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r);
605327fcede3SMatthew G. Knepley         orntNew[1] = 0;
605427fcede3SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax);
605527fcede3SMatthew G. Knepley         orntNew[2] = 0;
605627fcede3SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd                                   - fMax) + (c - cMax);
605727fcede3SMatthew G. Knepley         orntNew[3] = 0;
6058d273725eSMatthew G. Knepley #else
6059d273725eSMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r;
6060d273725eSMatthew G. Knepley         orntNew[0] = 0;
6061d273725eSMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r;
6062d273725eSMatthew G. Knepley         orntNew[1] = 0;
6063d273725eSMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax);
6064d273725eSMatthew G. Knepley         orntNew[2] = 0;
6065d273725eSMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd      - fMax) + (c - cMax);
6066d273725eSMatthew G. Knepley         orntNew[3] = 0;
6067d273725eSMatthew G. Knepley #endif
606827fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
606927fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
607027fcede3SMatthew G. Knepley #if 1
607127fcede3SMatthew 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);
607227fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
607327fcede3SMatthew 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);
607427fcede3SMatthew G. Knepley         }
607527fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
607627fcede3SMatthew 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);
607727fcede3SMatthew G. Knepley         }
607827fcede3SMatthew G. Knepley #endif
607927fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r);
608027fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4);
608127fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
608227fcede3SMatthew G. Knepley #if 1
608327fcede3SMatthew 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);
608427fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
608527fcede3SMatthew 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);
608627fcede3SMatthew G. Knepley         }
608727fcede3SMatthew G. Knepley #endif
608827fcede3SMatthew G. Knepley       }
608927fcede3SMatthew G. Knepley     }
609027fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
609127fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
609227fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
609327fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
609427fcede3SMatthew G. Knepley 
609527fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
609627fcede3SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
609727fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
609827fcede3SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
609927fcede3SMatthew G. Knepley 
610027fcede3SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
610127fcede3SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
610227fcede3SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
610327fcede3SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
610427fcede3SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
610527fcede3SMatthew G. Knepley #if 1
610627fcede3SMatthew 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);
610727fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
610827fcede3SMatthew 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);
610927fcede3SMatthew G. Knepley         }
611027fcede3SMatthew G. Knepley #endif
611127fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
611227fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
611327fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
611427fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
611527fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
611627fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
611727fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
611827fcede3SMatthew G. Knepley             if (cone[c] == e) break;
611927fcede3SMatthew G. Knepley           }
612027fcede3SMatthew G. Knepley           if (support[s] < fMax) {
612127fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4;
612227fcede3SMatthew G. Knepley           } else {
612327fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
612427fcede3SMatthew G. Knepley           }
612527fcede3SMatthew G. Knepley         }
612627fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
612727fcede3SMatthew G. Knepley #if 1
612827fcede3SMatthew 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);
612927fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
613027fcede3SMatthew 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);
613127fcede3SMatthew G. Knepley         }
613227fcede3SMatthew G. Knepley #endif
613327fcede3SMatthew G. Knepley       }
613427fcede3SMatthew G. Knepley     }
613527fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
613627fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
613727fcede3SMatthew 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};
613827fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
613927fcede3SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
614027fcede3SMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
614127fcede3SMatthew G. Knepley 
614227fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
614327fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
614427fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
614527fcede3SMatthew G. Knepley 
614627fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
614727fcede3SMatthew G. Knepley         coneNew[1] = newv;
614827fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
614927fcede3SMatthew G. Knepley #if 1
615027fcede3SMatthew 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);
615127fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
615227fcede3SMatthew 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);
615327fcede3SMatthew G. Knepley         }
615427fcede3SMatthew G. Knepley #endif
615527fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
615627fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
615727fcede3SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
615827fcede3SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
615927fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
616027fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
616127fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
616227fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
616327fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
616427fcede3SMatthew G. Knepley           if (support[s] < cMax) {
616527fcede3SMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
616627fcede3SMatthew G. Knepley           } else {
6167d273725eSMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r;
616827fcede3SMatthew G. Knepley           }
616927fcede3SMatthew G. Knepley         }
617027fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
617127fcede3SMatthew G. Knepley #if 1
617227fcede3SMatthew 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);
617327fcede3SMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
617427fcede3SMatthew 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);
617527fcede3SMatthew G. Knepley         }
617627fcede3SMatthew G. Knepley #endif
617727fcede3SMatthew G. Knepley       }
617827fcede3SMatthew G. Knepley     }
617927fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
618027fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
618127fcede3SMatthew 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};
618227fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
618327fcede3SMatthew G. Knepley       const PetscInt *cone;
618427fcede3SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
618527fcede3SMatthew G. Knepley 
618627fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
618727fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
618827fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
618927fcede3SMatthew G. Knepley 
619027fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart);
619127fcede3SMatthew G. Knepley         coneNew[1] = newv;
619227fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
619327fcede3SMatthew G. Knepley #if 1
619427fcede3SMatthew 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);
619527fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
619627fcede3SMatthew 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);
619727fcede3SMatthew G. Knepley         }
619827fcede3SMatthew G. Knepley #endif
619927fcede3SMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
620027fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
620127fcede3SMatthew G. Knepley #if 1
620227fcede3SMatthew 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);
620327fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
620427fcede3SMatthew 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);
620527fcede3SMatthew G. Knepley         }
620627fcede3SMatthew G. Knepley #endif
620727fcede3SMatthew G. Knepley       }
620827fcede3SMatthew G. Knepley     }
620927fcede3SMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
621027fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
621127fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
621227fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
621327fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
621427fcede3SMatthew G. Knepley 
621527fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
621627fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
621727fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
621827fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
621927fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
622027fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
622127fcede3SMatthew G. Knepley #if 1
622227fcede3SMatthew 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);
622327fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
622427fcede3SMatthew 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);
622527fcede3SMatthew G. Knepley       }
622627fcede3SMatthew G. Knepley #endif
622727fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
622827fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
622927fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
623027fcede3SMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
623127fcede3SMatthew 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]);
623227fcede3SMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2;
623327fcede3SMatthew G. Knepley       }
623427fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
623527fcede3SMatthew G. Knepley #if 1
623627fcede3SMatthew 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);
623727fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
623827fcede3SMatthew 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);
623927fcede3SMatthew G. Knepley       }
624027fcede3SMatthew G. Knepley #endif
624127fcede3SMatthew G. Knepley     }
624227fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
624327fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
624427fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
624527fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
624627fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
624727fcede3SMatthew G. Knepley 
624827fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
624927fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
625027fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
625127fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
625227fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
625327fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
625427fcede3SMatthew G. Knepley #if 1
625527fcede3SMatthew 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);
625627fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
625727fcede3SMatthew 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);
625827fcede3SMatthew G. Knepley       }
625927fcede3SMatthew G. Knepley #endif
626027fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0;
626127fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1;
626227fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
626327fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
626427fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
626527fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
626627fcede3SMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
626727fcede3SMatthew 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]);
6268d273725eSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2;
626927fcede3SMatthew G. Knepley       }
627027fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
627127fcede3SMatthew G. Knepley #if 1
627227fcede3SMatthew 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);
627327fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
627427fcede3SMatthew 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);
627527fcede3SMatthew G. Knepley       }
627627fcede3SMatthew G. Knepley #endif
627727fcede3SMatthew G. Knepley     }
627827fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
627927fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
628027fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
628127fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
628227fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size;
628327fcede3SMatthew G. Knepley 
628427fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
628527fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr);
628627fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr);
628727fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart);
628827fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart);
628927fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
629027fcede3SMatthew G. Knepley #if 1
629127fcede3SMatthew 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);
629227fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
629327fcede3SMatthew 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);
629427fcede3SMatthew G. Knepley       }
629527fcede3SMatthew G. Knepley #endif
629627fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0;
629727fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1;
629827fcede3SMatthew G. Knepley       supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2;
629927fcede3SMatthew G. Knepley       supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3;
630027fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
630127fcede3SMatthew G. Knepley #if 1
630227fcede3SMatthew 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);
630327fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
630427fcede3SMatthew 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);
630527fcede3SMatthew G. Knepley       }
630627fcede3SMatthew G. Knepley #endif
630727fcede3SMatthew G. Knepley     }
630827fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
630927fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
631027fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
631127fcede3SMatthew G. Knepley       const PetscInt *support, *cone;
631227fcede3SMatthew G. Knepley       PetscInt        size, s;
631327fcede3SMatthew G. Knepley 
631427fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
631527fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
631627fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
631727fcede3SMatthew G. Knepley         PetscInt r = 0;
631827fcede3SMatthew G. Knepley 
631927fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
632027fcede3SMatthew G. Knepley         if (cone[1] == v) r = 1;
632127fcede3SMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
632227fcede3SMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax);
632327fcede3SMatthew G. Knepley       }
632427fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
632527fcede3SMatthew G. Knepley #if 1
632627fcede3SMatthew 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);
632727fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
632827fcede3SMatthew 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);
632927fcede3SMatthew G. Knepley       }
633027fcede3SMatthew G. Knepley #endif
633127fcede3SMatthew G. Knepley     }
633227fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
633327fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
633427fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
633527fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
633627fcede3SMatthew G. Knepley       PetscInt        size, s;
633727fcede3SMatthew G. Knepley 
633827fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
633927fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
634027fcede3SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
634127fcede3SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
634227fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
634327fcede3SMatthew G. Knepley         PetscInt r;
634427fcede3SMatthew G. Knepley 
634527fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
634627fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
634727fcede3SMatthew G. Knepley         if (support[s] < fMax) {
634827fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r;
634927fcede3SMatthew G. Knepley         } else {
635027fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax);
635127fcede3SMatthew G. Knepley         }
635227fcede3SMatthew G. Knepley       }
635327fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
635427fcede3SMatthew G. Knepley #if 1
635527fcede3SMatthew 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);
635627fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
635727fcede3SMatthew 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);
635827fcede3SMatthew G. Knepley       }
635927fcede3SMatthew G. Knepley #endif
636027fcede3SMatthew G. Knepley     }
636127fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
636227fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
636327fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
636427fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
636527fcede3SMatthew G. Knepley       PetscInt        size, s;
636627fcede3SMatthew G. Knepley 
636727fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
636827fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
636927fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 +  (f - fStart)*4 + r;
637027fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
637127fcede3SMatthew G. Knepley         PetscInt r;
637227fcede3SMatthew G. Knepley 
637327fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
637427fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
637527fcede3SMatthew G. Knepley         if (support[s] < cMax) {
637627fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r;
637727fcede3SMatthew G. Knepley         } else {
637827fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax       - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax);
637927fcede3SMatthew G. Knepley         }
638027fcede3SMatthew G. Knepley       }
638127fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
638227fcede3SMatthew G. Knepley #if 1
638327fcede3SMatthew 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);
638427fcede3SMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
638527fcede3SMatthew 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);
638627fcede3SMatthew G. Knepley       }
638727fcede3SMatthew G. Knepley #endif
638827fcede3SMatthew G. Knepley     }
638927fcede3SMatthew G. Knepley     /* Cell vertices have 6 supports */
639027fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
639127fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
639227fcede3SMatthew G. Knepley       PetscInt       supportNew[6];
639327fcede3SMatthew G. Knepley 
639427fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
639527fcede3SMatthew G. Knepley         supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
639627fcede3SMatthew G. Knepley       }
639727fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
639827fcede3SMatthew G. Knepley     }
639927fcede3SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
640027fcede3SMatthew G. Knepley     break;
640175d3a19aSMatthew G. Knepley   default:
640275d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
640375d3a19aSMatthew G. Knepley   }
640475d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
640575d3a19aSMatthew G. Knepley }
640675d3a19aSMatthew G. Knepley 
640786150812SJed Brown static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
640875d3a19aSMatthew G. Knepley {
640975d3a19aSMatthew G. Knepley   PetscSection   coordSection, coordSectionNew;
641075d3a19aSMatthew G. Knepley   Vec            coordinates, coordinatesNew;
641175d3a19aSMatthew G. Knepley   PetscScalar   *coords, *coordsNew;
64123478d7aaSMatthew G. Knepley   const PetscInt numVertices = depthSize ? depthSize[0] : 0;
6413a57030b0SMatthew G. Knepley   PetscInt       dim, spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f;
64148b9ced59SLisandro Dalcin   VecType        vtype;
641575d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
641675d3a19aSMatthew G. Knepley 
641775d3a19aSMatthew G. Knepley   PetscFunctionBegin;
6418a57030b0SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
641975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
642075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
6421b5da9499SMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
642275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
642375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
642427fcede3SMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr);
64253478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);}
642675d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);
6427f719d809SMatthew G. Knepley   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
6428f1d7821bSLawrence Mitchell   ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr);
642975d3a19aSMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr);
643075d3a19aSMatthew G. Knepley   ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr);
6431f1d7821bSLawrence Mitchell   ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr);
64323478d7aaSMatthew G. Knepley   ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr);
643327fcede3SMatthew G. Knepley   if (cMax < 0) cMax = cEnd;
643475d3a19aSMatthew G. Knepley   if (fMax < 0) fMax = fEnd;
6435b5da9499SMatthew G. Knepley   if (eMax < 0) eMax = eEnd;
6436f1d7821bSLawrence Mitchell   /* All vertices have the spaceDim coordinates */
64373478d7aaSMatthew G. Knepley   for (v = vStartNew; v < vStartNew+numVertices; ++v) {
6438f1d7821bSLawrence Mitchell     ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr);
6439f1d7821bSLawrence Mitchell     ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr);
644075d3a19aSMatthew G. Knepley   }
644175d3a19aSMatthew G. Knepley   ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr);
644246e270d4SMatthew G. Knepley   ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr);
644375d3a19aSMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
644475d3a19aSMatthew G. Knepley   ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr);
64458b9ced59SLisandro Dalcin   ierr = VecCreate(PETSC_COMM_SELF, &coordinatesNew);CHKERRQ(ierr);
644675d3a19aSMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr);
644775d3a19aSMatthew G. Knepley   ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr);
644860b9e8a1SMatthew G. Knepley   ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr);
644960b9e8a1SMatthew G. Knepley   ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr);
64508b9ced59SLisandro Dalcin   ierr = VecGetType(coordinates, &vtype);CHKERRQ(ierr);
64518b9ced59SLisandro Dalcin   ierr = VecSetType(coordinatesNew, vtype);CHKERRQ(ierr);
645275d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr);
645375d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
6454b5da9499SMatthew G. Knepley   switch (refiner) {
64559b1a0e7fSLawrence Mitchell   case REFINER_NOOP: break;
6456*e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_3D:
64579b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
64589b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
6459b5da9499SMatthew G. Knepley     /* Face vertices have the average of corner coordinates */
6460d856d60fSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
646127fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
6462b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
6463b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
6464b5da9499SMatthew G. Knepley 
6465b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
6466b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
6467b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
6468b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
6469b5da9499SMatthew G. Knepley       }
6470b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
6471b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
6472b5da9499SMatthew G. Knepley       }
6473b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
6474f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
64752e17dfb7SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);}
6476f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
6477b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
6478b5da9499SMatthew G. Knepley     }
6479*e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_2D:
64809b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
64819b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
6482383c10e6SMatthew G. Knepley   case REFINER_SIMPLEX_1D:
6483b5da9499SMatthew G. Knepley     /* Cell vertices have the average of corner coordinates */
648427fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
64852ed5862eSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (dim > 1 ? (eMax - eStart) : 0) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0);
6486b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
6487b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
6488b5da9499SMatthew G. Knepley 
6489b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
6490b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
6491b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
6492b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
6493b5da9499SMatthew G. Knepley       }
6494b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
6495b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
6496b5da9499SMatthew G. Knepley       }
6497b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
6498f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
64992e17dfb7SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);}
6500f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
6501b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
6502b5da9499SMatthew G. Knepley     }
65039b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
65049b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
65059b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
65069b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
6507b5da9499SMatthew G. Knepley     /* Edge vertices have the average of endpoint coordinates */
6508b5da9499SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
6509b5da9499SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (e - eStart);
6510b5da9499SMatthew G. Knepley       const PetscInt *cone;
6511b5da9499SMatthew G. Knepley       PetscInt        coneSize, offA, offB, offnew, d;
6512b5da9499SMatthew G. Knepley 
6513b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr);
6514b5da9499SMatthew G. Knepley       if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize);
6515b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
6516b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr);
6517b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr);
6518b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
65192e17dfb7SMatthew G. Knepley       ierr = DMLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr);
6520f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) {
6521a96104c9SMatthew G. Knepley         coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]);
6522b5da9499SMatthew G. Knepley       }
6523b5da9499SMatthew G. Knepley     }
652475d3a19aSMatthew G. Knepley     /* Old vertices have the same coordinates */
652575d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
652675d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (v - vStart);
652775d3a19aSMatthew G. Knepley       PetscInt       off, offnew, d;
652875d3a19aSMatthew G. Knepley 
652975d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr);
653075d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
6531f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) {
653275d3a19aSMatthew G. Knepley         coordsNew[offnew+d] = coords[off+d];
653375d3a19aSMatthew G. Knepley       }
653475d3a19aSMatthew G. Knepley     }
6535b5da9499SMatthew G. Knepley     break;
6536b5da9499SMatthew G. Knepley   default:
6537b5da9499SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
653875d3a19aSMatthew G. Knepley   }
653975d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr);
654075d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
654175d3a19aSMatthew G. Knepley   ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr);
654275d3a19aSMatthew G. Knepley   ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr);
654375d3a19aSMatthew G. Knepley   ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr);
6544a96104c9SMatthew G. Knepley   if (dm->maxCell) {
6545a96104c9SMatthew G. Knepley     const PetscReal *maxCell, *L;
65465dc8c3f7SMatthew G. Knepley     const DMBoundaryType *bd;
65475dc8c3f7SMatthew G. Knepley     ierr = DMGetPeriodicity(dm,  &maxCell, &L, &bd);CHKERRQ(ierr);
65485dc8c3f7SMatthew G. Knepley     ierr = DMSetPeriodicity(rdm,  maxCell,  L,  bd);CHKERRQ(ierr);
6549a96104c9SMatthew G. Knepley   }
655075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
655175d3a19aSMatthew G. Knepley }
655275d3a19aSMatthew G. Knepley 
6553963fc26aSMatthew G. Knepley /*@
6554963fc26aSMatthew G. Knepley   DMPlexCreateProcessSF - Create an SF which just has process connectivity
6555963fc26aSMatthew G. Knepley 
6556963fc26aSMatthew G. Knepley   Collective on DM
6557963fc26aSMatthew G. Knepley 
6558963fc26aSMatthew G. Knepley   Input Parameters:
6559963fc26aSMatthew G. Knepley + dm      - The DM
6560963fc26aSMatthew G. Knepley - sfPoint - The PetscSF which encodes point connectivity
6561963fc26aSMatthew G. Knepley 
6562963fc26aSMatthew G. Knepley   Output Parameters:
6563963fc26aSMatthew G. Knepley + processRanks - A list of process neighbors, or NULL
6564963fc26aSMatthew G. Knepley - sfProcess    - An SF encoding the process connectivity, or NULL
6565963fc26aSMatthew G. Knepley 
6566963fc26aSMatthew G. Knepley   Level: developer
6567963fc26aSMatthew G. Knepley 
6568963fc26aSMatthew G. Knepley .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF()
6569963fc26aSMatthew G. Knepley @*/
6570963fc26aSMatthew G. Knepley PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
657175d3a19aSMatthew G. Knepley {
657275d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, l;
657375d3a19aSMatthew G. Knepley   const PetscInt    *localPoints;
657475d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
657575d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
657675d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
657775d3a19aSMatthew G. Knepley   PetscInt          *ranks, *ranksNew;
65789852e123SBarry Smith   PetscMPIInt        size;
657975d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
658075d3a19aSMatthew G. Knepley 
658175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
6582963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6583963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2);
6584963fc26aSMatthew G. Knepley   if (processRanks) {PetscValidPointer(processRanks, 3);}
6585963fc26aSMatthew G. Knepley   if (sfProcess)    {PetscValidPointer(sfProcess, 4);}
65869852e123SBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr);
658775d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
6588785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr);
658975d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
659075d3a19aSMatthew G. Knepley     ranks[l] = remotePoints[l].rank;
659175d3a19aSMatthew G. Knepley   }
659275d3a19aSMatthew G. Knepley   ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr);
6593785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr);
6594785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr);
6595785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr);
659675d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
659775d3a19aSMatthew G. Knepley     ranksNew[l]              = ranks[l];
659875d3a19aSMatthew G. Knepley     localPointsNew[l]        = l;
659975d3a19aSMatthew G. Knepley     remotePointsNew[l].index = 0;
660075d3a19aSMatthew G. Knepley     remotePointsNew[l].rank  = ranksNew[l];
660175d3a19aSMatthew G. Knepley   }
660275d3a19aSMatthew G. Knepley   ierr = PetscFree(ranks);CHKERRQ(ierr);
6603963fc26aSMatthew G. Knepley   if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);}
6604963fc26aSMatthew G. Knepley   else              {ierr = PetscFree(ranksNew);CHKERRQ(ierr);}
6605963fc26aSMatthew G. Knepley   if (sfProcess) {
660675d3a19aSMatthew G. Knepley     ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr);
6607963fc26aSMatthew G. Knepley     ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr);
660875d3a19aSMatthew G. Knepley     ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr);
66099852e123SBarry Smith     ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
6610963fc26aSMatthew G. Knepley   }
661175d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
661275d3a19aSMatthew G. Knepley }
661375d3a19aSMatthew G. Knepley 
661486150812SJed Brown static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
661575d3a19aSMatthew G. Knepley {
661675d3a19aSMatthew G. Knepley   PetscSF            sf, sfNew, sfProcess;
661775d3a19aSMatthew G. Knepley   IS                 processRanks;
661875d3a19aSMatthew G. Knepley   MPI_Datatype       depthType;
661975d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, numLeavesNew = 0, l, m;
662075d3a19aSMatthew G. Knepley   const PetscInt    *localPoints, *neighbors;
662175d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
662275d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
662375d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
662475d3a19aSMatthew G. Knepley   PetscInt          *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew;
662537d81139SMatthew G. Knepley   PetscInt           ldepth, depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n;
66267ba685a0SMatthew G. Knepley   PetscInt           cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
662775d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
662875d3a19aSMatthew G. Knepley 
662975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
663075d3a19aSMatthew G. Knepley   ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr);
663137d81139SMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &ldepth);CHKERRQ(ierr);
663237d81139SMatthew G. Knepley   ierr = MPIU_Allreduce(&ldepth, &depth, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr);
663337d81139SMatthew G. Knepley   if ((ldepth >= 0) && (depth != ldepth)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent Plex depth %d != %d", ldepth, depth);
663475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
663575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
663675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
663775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
663875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
6639add09238SMatthew G. Knepley   cMax = cMax < 0 ? cEnd : cMax;
6640add09238SMatthew G. Knepley   fMax = fMax < 0 ? fEnd : fMax;
6641add09238SMatthew G. Knepley   eMax = eMax < 0 ? eEnd : eMax;
66423478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
664375d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
664475d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr);
6645add09238SMatthew G. Knepley   /* Calculate size of new SF */
664675d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
664775d3a19aSMatthew G. Knepley   if (numRoots < 0) PetscFunctionReturn(0);
664875d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
664975d3a19aSMatthew G. Knepley     const PetscInt p = localPoints[l];
665075d3a19aSMatthew G. Knepley 
665175d3a19aSMatthew G. Knepley     switch (refiner) {
66520314a74cSLawrence Mitchell     case REFINER_SIMPLEX_1D:
66530314a74cSLawrence Mitchell       if ((p >= vStart) && (p < vEnd)) {
66540314a74cSLawrence Mitchell         /* Interior vertices stay the same */
66550314a74cSLawrence Mitchell         ++numLeavesNew;
66560314a74cSLawrence Mitchell       } else if ((p >= cStart && p < cMax)) {
66570314a74cSLawrence Mitchell         /* Interior cells add new cells and interior vertices */
66580314a74cSLawrence Mitchell         numLeavesNew += 2 + 1;
66590314a74cSLawrence Mitchell       }
66600314a74cSLawrence Mitchell       break;
66619b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_2D:
66629b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_2D:
6663a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
6664a97b51b8SMatthew G. Knepley         /* Interior vertices stay the same */
6665a97b51b8SMatthew G. Knepley         ++numLeavesNew;
6666a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
6667a97b51b8SMatthew G. Knepley         /* Interior faces add new faces and vertex */
6668a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
6669a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
6670a97b51b8SMatthew G. Knepley         /* Hybrid faces stay the same */
6671a97b51b8SMatthew G. Knepley         ++numLeavesNew;
6672a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
6673a97b51b8SMatthew G. Knepley         /* Interior cells add new cells and interior faces */
6674a97b51b8SMatthew G. Knepley         numLeavesNew += 4 + 3;
6675a97b51b8SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
6676a97b51b8SMatthew G. Knepley         /* Hybrid cells add new cells and hybrid face */
6677a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
6678a97b51b8SMatthew G. Knepley       }
6679a97b51b8SMatthew G. Knepley       break;
6680*e5337592SStefano Zampini     case REFINER_SIMPLEX_TO_HEX_2D:
6681*e5337592SStefano Zampini       if ((p >= vStart) && (p < vEnd)) {
6682*e5337592SStefano Zampini         /* Interior vertices stay the same */
6683*e5337592SStefano Zampini         ++numLeavesNew;
6684*e5337592SStefano Zampini       } else if ((p >= fStart) && (p < fEnd)) {
6685*e5337592SStefano Zampini         /* Interior faces add new faces and vertex */
6686*e5337592SStefano Zampini         numLeavesNew += 2 + 1;
6687*e5337592SStefano Zampini       } else if ((p >= cStart) && (p < cEnd)) {
6688*e5337592SStefano Zampini         /* Interior cells add new cells, interior faces, and vertex */
6689*e5337592SStefano Zampini         numLeavesNew += 3 + 3 + 1;
6690*e5337592SStefano Zampini       }
6691*e5337592SStefano Zampini       break;
66929b1a0e7fSLawrence Mitchell     case REFINER_HEX_2D:
66939b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_2D:
6694a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
6695a97b51b8SMatthew G. Knepley         /* Interior vertices stay the same */
6696a97b51b8SMatthew G. Knepley         ++numLeavesNew;
6697a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
6698a97b51b8SMatthew G. Knepley         /* Interior faces add new faces and vertex */
6699a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
6700a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
6701a97b51b8SMatthew G. Knepley         /* Hybrid faces stay the same */
6702a97b51b8SMatthew G. Knepley         ++numLeavesNew;
6703a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
6704a97b51b8SMatthew G. Knepley         /* Interior cells add new cells, interior faces, and vertex */
6705a97b51b8SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
6706a97b51b8SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
6707a97b51b8SMatthew G. Knepley         /* Hybrid cells add new cells and hybrid face */
6708a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
6709a97b51b8SMatthew G. Knepley       }
6710a97b51b8SMatthew G. Knepley       break;
67119b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_3D:
67129b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_3D:
67136ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
67146ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
67156ce3c06aSMatthew G. Knepley         ++numLeavesNew;
67166ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
67176ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
67186ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
67196ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
67206ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
67216ce3c06aSMatthew G. Knepley         ++numLeavesNew;
67226ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
67236ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
67246ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
67256ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
67266ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
67276ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
67286ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
67296ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
67306ce3c06aSMatthew G. Knepley         numLeavesNew += 8 + 8 + 1;
67316ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
67326ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
67336ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
67346ce3c06aSMatthew G. Knepley       }
67356ce3c06aSMatthew G. Knepley       break;
6736*e5337592SStefano Zampini     case REFINER_SIMPLEX_TO_HEX_3D:
6737*e5337592SStefano Zampini       if ((p >= vStart) && (p < vEnd)) {
6738*e5337592SStefano Zampini         /* Interior vertices stay the same */
6739*e5337592SStefano Zampini         ++numLeavesNew;
6740*e5337592SStefano Zampini       } else if ((p >= eStart) && (p < eEnd)) {
6741*e5337592SStefano Zampini         /* Interior edges add new edges and vertex */
6742*e5337592SStefano Zampini         numLeavesNew += 2 + 1;
6743*e5337592SStefano Zampini       } else if ((p >= fStart) && (p < fEnd)) {
6744*e5337592SStefano Zampini         /* Interior faces add new faces, edges and a vertex */
6745*e5337592SStefano Zampini         numLeavesNew += 3 + 3 + 1;
6746*e5337592SStefano Zampini       } else if ((p >= cStart) && (p < cEnd)) {
6747*e5337592SStefano Zampini         /* Interior cells add new cells, faces, edges and a vertex */
6748*e5337592SStefano Zampini         numLeavesNew += 4 + 6 + 4 + 1;
6749*e5337592SStefano Zampini       }
6750*e5337592SStefano Zampini       break;
67519b1a0e7fSLawrence Mitchell     case REFINER_HEX_3D:
67529b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_3D:
675327fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
675427fcede3SMatthew G. Knepley         /* Old vertices stay the same */
675527fcede3SMatthew G. Knepley         ++numLeavesNew;
675627fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
675727fcede3SMatthew G. Knepley         /* Interior edges add new edges, and vertex */
675827fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
675927fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
676027fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
676127fcede3SMatthew G. Knepley         ++numLeavesNew;
676227fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
676327fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
676427fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
676527fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
676627fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
676727fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
676827fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
676927fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
677027fcede3SMatthew G. Knepley         numLeavesNew += 8 + 12 + 6 + 1;
677127fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
677227fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
677327fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
677427fcede3SMatthew G. Knepley       }
677527fcede3SMatthew G. Knepley       break;
677675d3a19aSMatthew G. Knepley     default:
677775d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
677875d3a19aSMatthew G. Knepley     }
677975d3a19aSMatthew G. Knepley   }
678075d3a19aSMatthew G. Knepley   /* Communicate depthSizes for each remote rank */
678175d3a19aSMatthew G. Knepley   ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr);
678275d3a19aSMatthew G. Knepley   ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr);
6783dcca6d9dSJed Brown   ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr);
6784dcca6d9dSJed Brown   ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr);
678575d3a19aSMatthew G. Knepley   ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr);
678675d3a19aSMatthew G. Knepley   ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr);
678775d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
678875d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
678975d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
679075d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr);
679175d3a19aSMatthew G. Knepley   }
679275d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cMax;
679375d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vMax;
679475d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fMax;
679575d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eMax;
679675d3a19aSMatthew G. Knepley 
679775d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
679875d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
679975d3a19aSMatthew G. Knepley 
680075d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cEnd - cStart;
680175d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vEnd - vStart;
680275d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fEnd - fStart;
680375d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eEnd - eStart;
680475d3a19aSMatthew G. Knepley 
680575d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
680675d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
680775d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
680875d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr);
68090252e7f5SMatthew 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];
68100252e7f5SMatthew 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];
68110252e7f5SMatthew 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];
681275d3a19aSMatthew G. Knepley   }
681375d3a19aSMatthew G. Knepley   ierr = MPI_Type_free(&depthType);CHKERRQ(ierr);
681475d3a19aSMatthew G. Knepley   ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr);
681575d3a19aSMatthew G. Knepley   /* Calculate new point SF */
6816785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr);
6817785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr);
681875d3a19aSMatthew G. Knepley   ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr);
681975d3a19aSMatthew G. Knepley   for (l = 0, m = 0; l < numLeaves; ++l) {
682075d3a19aSMatthew G. Knepley     PetscInt    p     = localPoints[l];
682175d3a19aSMatthew G. Knepley     PetscInt    rp    = remotePoints[l].index, n;
682275d3a19aSMatthew G. Knepley     PetscMPIInt rrank = remotePoints[l].rank;
682375d3a19aSMatthew G. Knepley 
682475d3a19aSMatthew G. Knepley     ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr);
682575d3a19aSMatthew G. Knepley     if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank);
682675d3a19aSMatthew G. Knepley     switch (refiner) {
68270314a74cSLawrence Mitchell     case REFINER_SIMPLEX_1D:
68280314a74cSLawrence Mitchell       if ((p >= vStart) && (p < vEnd)) {
68290314a74cSLawrence Mitchell         /* Old vertices stay the same */
68300314a74cSLawrence Mitchell         localPointsNew[m]        = vStartNew     + (p  - vStart);
68310314a74cSLawrence Mitchell         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
68320314a74cSLawrence Mitchell         remotePointsNew[m].rank  = rrank;
68330314a74cSLawrence Mitchell         ++m;
68340314a74cSLawrence Mitchell       } else if ((p >= cStart) && (p < cMax)) {
68350314a74cSLawrence Mitchell         /* Old interior cells add new cells and vertex */
68360314a74cSLawrence Mitchell         for (r = 0; r < 2; ++r, ++m) {
68370314a74cSLawrence Mitchell           localPointsNew[m]        = cStartNew     + (p  - cStart)*2     + r;
68380314a74cSLawrence Mitchell           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r;
68390314a74cSLawrence Mitchell           remotePointsNew[m].rank  = rrank;
68400314a74cSLawrence Mitchell         }
68410314a74cSLawrence Mitchell         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - cStart);
68420314a74cSLawrence Mitchell         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]);
68430314a74cSLawrence Mitchell         remotePointsNew[m].rank  = rrank;
68440314a74cSLawrence Mitchell         ++m;
68450314a74cSLawrence Mitchell       }
68460314a74cSLawrence Mitchell       break;
68479b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_2D:
68489b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_2D:
684975d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
685075d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
685175d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
685275d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
685375d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
685475d3a19aSMatthew G. Knepley         ++m;
685575d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
685675d3a19aSMatthew G. Knepley         /* Old interior faces add new faces and vertex */
685775d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
685875d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
685975d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
686075d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
686175d3a19aSMatthew G. Knepley         }
6862add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
6863add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
6864add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
6865add09238SMatthew G. Knepley         ++m;
686675d3a19aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
686775d3a19aSMatthew G. Knepley         /* Old hybrid faces stay the same */
686875d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
686975d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
687075d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
687175d3a19aSMatthew G. Knepley         ++m;
687275d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
687375d3a19aSMatthew G. Knepley         /* Old interior cells add new cells and interior faces */
687475d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
687575d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
687675d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
687775d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
687875d3a19aSMatthew G. Knepley         }
687975d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
688075d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*3     + r;
688175d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r;
688275d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
688375d3a19aSMatthew G. Knepley         }
6884add09238SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
688575d3a19aSMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
688675d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
688775d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
688875d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
688975d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
689075d3a19aSMatthew G. Knepley         }
689175d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*3     + (p  - cMax);
689275d3a19aSMatthew 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]);
689375d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
689475d3a19aSMatthew G. Knepley         ++m;
689575d3a19aSMatthew G. Knepley       }
689675d3a19aSMatthew G. Knepley       break;
6897*e5337592SStefano Zampini     case REFINER_SIMPLEX_TO_HEX_2D:
6898*e5337592SStefano Zampini       if ((p >= vStart) && (p < vEnd)) {
6899*e5337592SStefano Zampini         /* Old vertices stay the same */
6900*e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (p  - vStart);
6901*e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
6902*e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
6903*e5337592SStefano Zampini         ++m;
6904*e5337592SStefano Zampini       } else if ((p >= fStart) && (p < fEnd)) {
6905*e5337592SStefano Zampini         /* Old interior faces add new faces and vertex */
6906*e5337592SStefano Zampini         for (r = 0; r < 2; ++r, ++m) {
6907*e5337592SStefano Zampini           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
6908*e5337592SStefano Zampini           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
6909*e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
6910*e5337592SStefano Zampini         }
6911*e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
6912*e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
6913*e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
6914*e5337592SStefano Zampini         ++m;
6915*e5337592SStefano Zampini       } else if ((p >= cStart) && (p < cEnd)) {
6916*e5337592SStefano Zampini         /* Old interior cells add new cells, interior faces, and a vertex */
6917*e5337592SStefano Zampini         for (r = 0; r < 3; ++r, ++m) {
6918*e5337592SStefano Zampini           localPointsNew[m]        = cStartNew     + (p  - cStart)*3     + r;
6919*e5337592SStefano Zampini           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*3 + r;
6920*e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
6921*e5337592SStefano Zampini         }
6922*e5337592SStefano Zampini         for (r = 0; r < 3; ++r, ++m) {
6923*e5337592SStefano Zampini           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*2                    + (p  - cStart)*3     + r;
6924*e5337592SStefano Zampini           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r;
6925*e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
6926*e5337592SStefano Zampini         }
6927*e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (fEnd - fStart)                    + (p  - cStart);
6928*e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]);
6929*e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
6930*e5337592SStefano Zampini         ++m;
6931*e5337592SStefano Zampini       }
6932*e5337592SStefano Zampini       break;
69339b1a0e7fSLawrence Mitchell     case REFINER_HEX_2D:
69349b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_2D:
6935a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
6936a97b51b8SMatthew G. Knepley         /* Old vertices stay the same */
6937a97b51b8SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
6938a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
6939a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
6940a97b51b8SMatthew G. Knepley         ++m;
6941a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
6942a97b51b8SMatthew G. Knepley         /* Old interior faces add new faces and vertex */
6943a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
6944a97b51b8SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
6945a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
6946a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
6947a97b51b8SMatthew G. Knepley         }
6948add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
6949add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
6950add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
6951add09238SMatthew G. Knepley         ++m;
6952a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
6953a97b51b8SMatthew G. Knepley         /* Old hybrid faces stay the same */
6954a97b51b8SMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
6955a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
6956a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
6957a97b51b8SMatthew G. Knepley         ++m;
6958a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
6959a97b51b8SMatthew G. Knepley         /* Old interior cells add new cells, interior faces, and vertex */
6960a97b51b8SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
6961a97b51b8SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
6962a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
6963a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
6964a97b51b8SMatthew G. Knepley         }
6965a97b51b8SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
6966a97b51b8SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*4     + r;
6967a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r;
6968a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
6969a97b51b8SMatthew G. Knepley         }
6970add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)               + (fMax                              - fStart)     + (p  - cStart);
6971add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0]  + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]);
6972add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
6973add09238SMatthew G. Knepley         ++m;
6974a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
6975a97b51b8SMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
6976a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
6977a97b51b8SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
6978a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
6979a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
6980a97b51b8SMatthew G. Knepley         }
6981a97b51b8SMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*4     + (p  - cMax);
6982a97b51b8SMatthew 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]);
6983a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
6984a97b51b8SMatthew G. Knepley         ++m;
6985a97b51b8SMatthew G. Knepley       }
6986a97b51b8SMatthew G. Knepley       break;
69879b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_3D:
69889b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_3D:
69896ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
69906ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
69916ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
69926ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
69936ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
69946ce3c06aSMatthew G. Knepley         ++m;
69956ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
69966ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
69976ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
69986ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
69996ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
70006ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
70016ce3c06aSMatthew G. Knepley         }
70026ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
70036ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
70046ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
70056ce3c06aSMatthew G. Knepley         ++m;
70066ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
70076ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
70086ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (p  - eMax);
70097d5cd7d5SMatthew 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]);
70106ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
70116ce3c06aSMatthew G. Knepley         ++m;
70126ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
70136ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
70146ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
70156ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
70166ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
70176ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
70186ce3c06aSMatthew G. Knepley         }
70196ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
70206ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*3     + r;
70216ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r;
70226ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
70236ce3c06aSMatthew G. Knepley         }
70246ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
70256ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
70266ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
7027899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (p  - fMax)*2                              + r;
7028899f98d0SMatthew 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;
70296ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
70306ce3c06aSMatthew G. Knepley         }
70317d5cd7d5SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (eEnd                                    - eMax)                        + (p  - fMax);
70327d5cd7d5SMatthew 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]);
70336ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
703409b1338fSMatthew G. Knepley         ++m;
70356ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
70366ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
70376ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
70386ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
70396ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
70406ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
70416ce3c06aSMatthew G. Knepley         }
70426ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
70436ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*8     + r;
70446ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r;
70456ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
70466ce3c06aSMatthew G. Knepley         }
7047c7c54c77SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (p  - cStart)*1     + 0;
7048c7c54c77SMatthew 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;
70496ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
705009b1338fSMatthew G. Knepley         ++m;
70516ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
70526ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
70536ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
70546ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
70556ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
70566ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
70576ce3c06aSMatthew G. Knepley         }
70586ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
7059899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (fEnd                                          - fMax)*2                              + (p  - cMax)*3                            + r;
7060899f98d0SMatthew 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;
70616ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
70626ce3c06aSMatthew G. Knepley         }
70636ce3c06aSMatthew G. Knepley       }
70646ce3c06aSMatthew G. Knepley       break;
7065*e5337592SStefano Zampini     case REFINER_SIMPLEX_TO_HEX_3D:
7066*e5337592SStefano Zampini       if ((p >= vStart) && (p < vEnd)) {
7067*e5337592SStefano Zampini         /* Interior vertices stay the same */
7068*e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (p  - vStart);
7069*e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
7070*e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7071*e5337592SStefano Zampini         ++m;
7072*e5337592SStefano Zampini       } else if ((p >= eStart) && (p < eEnd)) {
7073*e5337592SStefano Zampini         /* Interior edges add new edges and vertex */
7074*e5337592SStefano Zampini         for (r = 0; r < 2; ++r, ++m) {
7075*e5337592SStefano Zampini           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
7076*e5337592SStefano Zampini           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
7077*e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7078*e5337592SStefano Zampini         }
7079*e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
7080*e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
7081*e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7082*e5337592SStefano Zampini         ++m;
7083*e5337592SStefano Zampini       } else if ((p >= fStart) && (p < fEnd)) {
7084*e5337592SStefano Zampini         /* Interior faces add new faces, edges and a vertex */
7085*e5337592SStefano Zampini         for (r = 0; r < 3; ++r, ++m) {
7086*e5337592SStefano Zampini           localPointsNew[m]        = fStartNew     + (p  - fStart)*3     + r;
7087*e5337592SStefano Zampini           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*3 + r;
7088*e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7089*e5337592SStefano Zampini         }
7090*e5337592SStefano Zampini         for (r = 0; r < 3; ++r, ++m) {
7091*e5337592SStefano Zampini           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2                + (p  - fStart)*3     + r;
7092*e5337592SStefano Zampini           remotePointsNew[m].index = reStartNew[n] + (rdepthSizeOld[n*(depth+1)+1])*2 + (rp - rfStart[n])*3 + r;
7093*e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7094*e5337592SStefano Zampini         }
7095*e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eEnd - eStart)              + (p - fStart);
7096*e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]);
7097*e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7098*e5337592SStefano Zampini         ++m;
7099*e5337592SStefano Zampini       } else if ((p >= cStart) && (p < cEnd)) {
7100*e5337592SStefano Zampini         /* Interior cells add new cells, faces, edges, and a vertex */
7101*e5337592SStefano Zampini         for (r = 0; r < 4; ++r, ++m) {
7102*e5337592SStefano Zampini           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
7103*e5337592SStefano Zampini           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
7104*e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7105*e5337592SStefano Zampini         }
7106*e5337592SStefano Zampini         for (r = 0; r < 6; ++r, ++m) {
7107*e5337592SStefano Zampini           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*3                    + (p  - cStart)*6     + r;
7108*e5337592SStefano Zampini           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*6 + r;
7109*e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7110*e5337592SStefano Zampini         }
7111*e5337592SStefano Zampini         for (r = 0; r < 4; ++r, ++m) {
7112*e5337592SStefano Zampini           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (fEnd - fStart)*3                    + (p  - cStart)*4 + r;
7113*e5337592SStefano Zampini           remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*4 + r;
7114*e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7115*e5337592SStefano Zampini         }
7116*e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eEnd - eStart)              + (fEnd - fStart)                    + (p - cStart);
7117*e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]);
7118*e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7119*e5337592SStefano Zampini         ++m;
7120*e5337592SStefano Zampini       }
7121*e5337592SStefano Zampini       break;
71229b1a0e7fSLawrence Mitchell     case REFINER_HEX_3D:
71239b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_3D:
712427fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
712527fcede3SMatthew G. Knepley         /* Interior vertices stay the same */
712627fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
712727fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
712827fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
712927fcede3SMatthew G. Knepley         ++m;
713027fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
713127fcede3SMatthew G. Knepley         /* Interior edges add new edges and vertex */
713227fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
713327fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
713427fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
713527fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
713627fcede3SMatthew G. Knepley         }
713727fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
713827fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
713927fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
714027fcede3SMatthew G. Knepley         ++m;
714127fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
714227fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
714327fcede3SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (p  - eMax);
7144d2701f60SMatthew 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]);
714527fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
714627fcede3SMatthew G. Knepley         ++m;
714727fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
714827fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
714927fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
715027fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
715127fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
715227fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
715327fcede3SMatthew G. Knepley         }
715427fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
715527fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*4     + r;
715627fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r;
715727fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
715827fcede3SMatthew G. Knepley         }
715927fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eMax                        - eStart)     + (p  - fStart);
716027fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]);
716127fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
716227fcede3SMatthew G. Knepley         ++m;
716327fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
716427fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
716527fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
7166d2701f60SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*12     + (p  - fMax)*2                              + r;
7167d2701f60SMatthew 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;
716827fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
716927fcede3SMatthew G. Knepley         }
7170d2701f60SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (eEnd                                    - eMax)                        + (p  - fMax);
7171d2701f60SMatthew 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]);
717227fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
717327fcede3SMatthew G. Knepley         ++m;
717427fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
717527fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
717627fcede3SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
717727fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
717827fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
717927fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
718027fcede3SMatthew G. Knepley         }
718127fcede3SMatthew G. Knepley         for (r = 0; r < 12; ++r, ++m) {
718227fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*12     + r;
718327fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r;
718427fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
718527fcede3SMatthew G. Knepley         }
718627fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r, ++m) {
718727fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (p  - cStart)*6     + r;
718827fcede3SMatthew 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;
718927fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
719027fcede3SMatthew G. Knepley         }
719127fcede3SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
719227fcede3SMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (eMax                        - eStart)     + (fMax                              - fStart)     + (p  - cStart)     + r;
719327fcede3SMatthew 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;
719427fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
719527fcede3SMatthew G. Knepley         }
719627fcede3SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
719727fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
719827fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
719927fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
720027fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
720127fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
720227fcede3SMatthew G. Knepley         }
720327fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
7204d2701f60SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*12     + (fEnd                                          - fMax)*2                              + (p  - cMax)*4                            + r;
7205d2701f60SMatthew 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;
720627fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
720727fcede3SMatthew G. Knepley         }
7208d2701f60SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (eEnd                                    - eMax)                        + (fEnd                                          - fMax)                              + (p  - cMax);
7209d2701f60SMatthew 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]);
721027fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
721127fcede3SMatthew G. Knepley         ++m;
721227fcede3SMatthew G. Knepley       }
721327fcede3SMatthew G. Knepley       break;
721475d3a19aSMatthew G. Knepley     default:
721575d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
721675d3a19aSMatthew G. Knepley     }
721775d3a19aSMatthew G. Knepley   }
721809b1338fSMatthew G. Knepley   if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew);
721975d3a19aSMatthew G. Knepley   ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr);
722075d3a19aSMatthew G. Knepley   ierr = ISDestroy(&processRanks);CHKERRQ(ierr);
7221ba3c3d50SMatthew G. Knepley   {
7222ba3c3d50SMatthew G. Knepley     PetscSFNode *rp, *rtmp;
7223ba3c3d50SMatthew G. Knepley     PetscInt    *lp, *idx, *ltmp, i;
7224ba3c3d50SMatthew G. Knepley 
7225ba3c3d50SMatthew G. Knepley     /* SF needs sorted leaves to correct calculate Gather */
7226ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr);
7227ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr);
7228ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr);
7229c7c54c77SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
7230c7c54c77SMatthew 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);
7231c7c54c77SMatthew G. Knepley       idx[i] = i;
7232c7c54c77SMatthew G. Knepley     }
7233ba3c3d50SMatthew G. Knepley     ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr);
7234ba3c3d50SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
7235ba3c3d50SMatthew G. Knepley       lp[i] = localPointsNew[idx[i]];
7236ba3c3d50SMatthew G. Knepley       rp[i] = remotePointsNew[idx[i]];
7237ba3c3d50SMatthew G. Knepley     }
7238ba3c3d50SMatthew G. Knepley     ltmp            = localPointsNew;
7239ba3c3d50SMatthew G. Knepley     localPointsNew  = lp;
7240ba3c3d50SMatthew G. Knepley     rtmp            = remotePointsNew;
7241ba3c3d50SMatthew G. Knepley     remotePointsNew = rp;
7242ba3c3d50SMatthew G. Knepley     ierr = PetscFree(idx);CHKERRQ(ierr);
7243ba3c3d50SMatthew G. Knepley     ierr = PetscFree(ltmp);CHKERRQ(ierr);
7244ba3c3d50SMatthew G. Knepley     ierr = PetscFree(rtmp);CHKERRQ(ierr);
7245ba3c3d50SMatthew G. Knepley   }
724675d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
724775d3a19aSMatthew G. Knepley   ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr);
724806a0ba2dSMatthew G. Knepley   ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr);
724975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
725075d3a19aSMatthew G. Knepley }
725175d3a19aSMatthew G. Knepley 
725286150812SJed Brown static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
725375d3a19aSMatthew G. Knepley {
725475d3a19aSMatthew G. Knepley   PetscInt       numLabels, l;
72557ba685a0SMatthew G. Knepley   PetscInt       depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r;
72567ba685a0SMatthew G. Knepley   PetscInt       cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
725775d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
725875d3a19aSMatthew G. Knepley 
725975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
726075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
726175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
726275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
726375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
7264d963de37SMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
72653478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
7266c58f1c22SToby Isaac   ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr);
726775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
726875d3a19aSMatthew G. Knepley   switch (refiner) {
72699b1a0e7fSLawrence Mitchell   case REFINER_NOOP:
72700314a74cSLawrence Mitchell   case REFINER_SIMPLEX_1D:
72719b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
7272*e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_2D:
72739b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
72749b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
72759b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
7276*e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_3D:
72779b1a0e7fSLawrence Mitchell     break;
72789b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
72799b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
728058b8852aSMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
72819b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
72829b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
728375d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
728475d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
72851e317b1dSMatthew G. Knepley     break;
72869b1a0e7fSLawrence Mitchell   default:
72879b1a0e7fSLawrence Mitchell     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
728875d3a19aSMatthew G. Knepley   }
728975d3a19aSMatthew G. Knepley   for (l = 0; l < numLabels; ++l) {
729075d3a19aSMatthew G. Knepley     DMLabel         label, labelNew;
729175d3a19aSMatthew G. Knepley     const char     *lname;
729275d3a19aSMatthew G. Knepley     PetscBool       isDepth;
729375d3a19aSMatthew G. Knepley     IS              valueIS;
729475d3a19aSMatthew G. Knepley     const PetscInt *values;
72955aa44df4SToby Isaac     PetscInt        defVal;
729675d3a19aSMatthew G. Knepley     PetscInt        numValues, val;
729775d3a19aSMatthew G. Knepley 
7298c58f1c22SToby Isaac     ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr);
729975d3a19aSMatthew G. Knepley     ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr);
730075d3a19aSMatthew G. Knepley     if (isDepth) continue;
7301c58f1c22SToby Isaac     ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr);
7302c58f1c22SToby Isaac     ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr);
7303c58f1c22SToby Isaac     ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr);
73045aa44df4SToby Isaac     ierr = DMLabelGetDefaultValue(label,&defVal);CHKERRQ(ierr);
73055aa44df4SToby Isaac     ierr = DMLabelSetDefaultValue(labelNew,defVal);CHKERRQ(ierr);
730675d3a19aSMatthew G. Knepley     ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr);
730775d3a19aSMatthew G. Knepley     ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr);
730875d3a19aSMatthew G. Knepley     ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr);
730975d3a19aSMatthew G. Knepley     for (val = 0; val < numValues; ++val) {
731075d3a19aSMatthew G. Knepley       IS              pointIS;
731175d3a19aSMatthew G. Knepley       const PetscInt *points;
731275d3a19aSMatthew G. Knepley       PetscInt        numPoints, n;
731375d3a19aSMatthew G. Knepley 
731475d3a19aSMatthew G. Knepley       ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr);
731575d3a19aSMatthew G. Knepley       ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);
731675d3a19aSMatthew G. Knepley       ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr);
73172bc5314cSMichael Lange       /* Ensure refined label is created with same number of strata as
73182bc5314cSMichael Lange        * original (even if no entries here). */
7319ad8374ffSToby Isaac       ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr);
732075d3a19aSMatthew G. Knepley       for (n = 0; n < numPoints; ++n) {
732175d3a19aSMatthew G. Knepley         const PetscInt p = points[n];
732275d3a19aSMatthew G. Knepley         switch (refiner) {
73230314a74cSLawrence Mitchell         case REFINER_SIMPLEX_1D:
73240314a74cSLawrence Mitchell           if ((p >= vStart) && (p < vEnd)) {
73250314a74cSLawrence Mitchell             /* Old vertices stay the same */
73260314a74cSLawrence Mitchell             newp = vStartNew + (p - vStart);
73270314a74cSLawrence Mitchell             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
73280314a74cSLawrence Mitchell           } else if ((p >= cStart) && (p < cEnd)) {
73290314a74cSLawrence Mitchell             /* Old cells add new cells and vertex */
73300314a74cSLawrence Mitchell             newp = vStartNew + (vEnd - vStart) + (p - cStart);
73310314a74cSLawrence Mitchell             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
73320314a74cSLawrence Mitchell             for (r = 0; r < 2; ++r) {
73330314a74cSLawrence Mitchell               newp = cStartNew + (p - cStart)*2 + r;
73340314a74cSLawrence Mitchell               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
73350314a74cSLawrence Mitchell             }
73360314a74cSLawrence Mitchell           }
73370314a74cSLawrence Mitchell           break;
73389b1a0e7fSLawrence Mitchell         case REFINER_SIMPLEX_2D:
733975d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
734075d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
734175d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
734275d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
734375d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
734475d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
734575d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
734675d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
734775d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
734875d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
734975d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
735075d3a19aSMatthew G. Knepley             }
735175d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
735275d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces */
735375d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
735475d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
735575d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
735675d3a19aSMatthew G. Knepley             }
735775d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
735875d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
735975d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
736075d3a19aSMatthew G. Knepley             }
736175d3a19aSMatthew G. Knepley           }
736275d3a19aSMatthew G. Knepley           break;
7363*e5337592SStefano Zampini         case REFINER_SIMPLEX_TO_HEX_2D:
7364*e5337592SStefano Zampini           if ((p >= vStart) && (p < vEnd)) {
7365*e5337592SStefano Zampini             /* Old vertices stay the same */
7366*e5337592SStefano Zampini             newp = vStartNew + (p - vStart);
7367*e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7368*e5337592SStefano Zampini           } else if ((p >= fStart) && (p < fEnd)) {
7369*e5337592SStefano Zampini             /* Old faces add new faces and vertex */
7370*e5337592SStefano Zampini             newp = vStartNew + (vEnd - vStart) + (p - fStart);
7371*e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7372*e5337592SStefano Zampini             for (r = 0; r < 2; ++r) {
7373*e5337592SStefano Zampini               newp = fStartNew + (p - fStart)*2 + r;
7374*e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7375*e5337592SStefano Zampini             }
7376*e5337592SStefano Zampini           } else if ((p >= cStart) && (p < cEnd)) {
7377*e5337592SStefano Zampini             /* Old cells add new cells, interior faces, and a vertex */
7378*e5337592SStefano Zampini             for (r = 0; r < 3; ++r) {
7379*e5337592SStefano Zampini               newp = cStartNew + (p - cStart)*3 + r;
7380*e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7381*e5337592SStefano Zampini             }
7382*e5337592SStefano Zampini             for (r = 0; r < 3; ++r) {
7383*e5337592SStefano Zampini               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
7384*e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7385*e5337592SStefano Zampini             }
7386*e5337592SStefano Zampini             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p;
7387*e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7388*e5337592SStefano Zampini           }
7389*e5337592SStefano Zampini           break;
73909b1a0e7fSLawrence Mitchell         case REFINER_HEX_2D:
739175d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
739275d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
739375d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
739475d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
739575d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
739675d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
739775d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
739875d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
739975d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
740075d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
740175d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
740275d3a19aSMatthew G. Knepley             }
740375d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
740475d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces and vertex */
740575d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
740675d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
740775d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
740875d3a19aSMatthew G. Knepley             }
740975d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
741075d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
741175d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
741275d3a19aSMatthew G. Knepley             }
741375d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
741475d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
741575d3a19aSMatthew G. Knepley           }
741675d3a19aSMatthew G. Knepley           break;
74179b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_SIMPLEX_2D:
741875d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
741975d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
742075d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
742175d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
742275d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
742375d3a19aSMatthew G. Knepley             /* Old interior faces add new faces and vertex */
742475d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
742575d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
742675d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
742775d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
742875d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
742975d3a19aSMatthew G. Knepley             }
743075d3a19aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
743175d3a19aSMatthew G. Knepley             /* Old hybrid faces stay the same */
743275d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
743375d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
743475d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
743575d3a19aSMatthew G. Knepley             /* Old interior cells add new cells and interior faces */
743675d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
743775d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
743875d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
743975d3a19aSMatthew G. Knepley             }
744075d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
744175d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
744275d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
744375d3a19aSMatthew G. Knepley             }
744475d3a19aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
744575d3a19aSMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
744675d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
744775d3a19aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
744875d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
744975d3a19aSMatthew G. Knepley             }
745075d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
745175d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
745275d3a19aSMatthew G. Knepley           }
745375d3a19aSMatthew G. Knepley           break;
74549b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_HEX_2D:
7455a97b51b8SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
7456a97b51b8SMatthew G. Knepley             /* Old vertices stay the same */
7457a97b51b8SMatthew G. Knepley             newp = vStartNew + (p - vStart);
7458a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7459a97b51b8SMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
7460a97b51b8SMatthew G. Knepley             /* Old interior faces add new faces and vertex */
7461a97b51b8SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
7462a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7463a97b51b8SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
7464a97b51b8SMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
7465a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7466a97b51b8SMatthew G. Knepley             }
7467a97b51b8SMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
7468a97b51b8SMatthew G. Knepley             /* Old hybrid faces stay the same */
7469a97b51b8SMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
7470a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7471a97b51b8SMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
7472a97b51b8SMatthew G. Knepley             /* Old interior cells add new cells, interior faces, and vertex */
7473a97b51b8SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
7474a97b51b8SMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
7475a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7476a97b51b8SMatthew G. Knepley             }
7477a97b51b8SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
7478a97b51b8SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
7479a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7480a97b51b8SMatthew G. Knepley             }
7481a97b51b8SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
7482a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7483a97b51b8SMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
7484a97b51b8SMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
7485a97b51b8SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
7486a97b51b8SMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
7487a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7488a97b51b8SMatthew G. Knepley             }
7489a97b51b8SMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax);
7490a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7491a97b51b8SMatthew G. Knepley           }
7492a97b51b8SMatthew G. Knepley           break;
74939b1a0e7fSLawrence Mitchell         case REFINER_SIMPLEX_3D:
7494b5da9499SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
7495b5da9499SMatthew G. Knepley             /* Old vertices stay the same */
7496b5da9499SMatthew G. Knepley             newp = vStartNew + (p - vStart);
7497b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7498b5da9499SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
7499b5da9499SMatthew G. Knepley             /* Old edges add new edges and vertex */
7500b5da9499SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
7501b5da9499SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
7502b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7503b5da9499SMatthew G. Knepley             }
7504b5da9499SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
7505b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7506b5da9499SMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
7507b5da9499SMatthew G. Knepley             /* Old faces add new faces and edges */
7508b5da9499SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
7509b5da9499SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
7510b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7511b5da9499SMatthew G. Knepley             }
7512b5da9499SMatthew G. Knepley             for (r = 0; r < 3; ++r) {
7513b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
7514b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7515b5da9499SMatthew G. Knepley             }
7516b5da9499SMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
7517b5da9499SMatthew G. Knepley             /* Old cells add new cells and interior faces and edges */
7518b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
7519b5da9499SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
7520b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7521b5da9499SMatthew G. Knepley             }
7522b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
7523b5da9499SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r;
7524b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7525b5da9499SMatthew G. Knepley             }
7526b5da9499SMatthew G. Knepley             for (r = 0; r < 1; ++r) {
7527b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r;
7528b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7529b5da9499SMatthew G. Knepley             }
7530b5da9499SMatthew G. Knepley           }
7531b5da9499SMatthew G. Knepley           break;
7532*e5337592SStefano Zampini         case REFINER_SIMPLEX_TO_HEX_3D:
7533*e5337592SStefano Zampini           if ((p >= vStart) && (p < vEnd)) {
7534*e5337592SStefano Zampini             /* Old vertices stay the same */
7535*e5337592SStefano Zampini             newp = vStartNew + (p - vStart);
7536*e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7537*e5337592SStefano Zampini           } else if ((p >= eStart) && (p < eEnd)) {
7538*e5337592SStefano Zampini             /* Old edges add new edges and vertex */
7539*e5337592SStefano Zampini             for (r = 0; r < 2; ++r) {
7540*e5337592SStefano Zampini               newp = eStartNew + (p - eStart)*2 + r;
7541*e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7542*e5337592SStefano Zampini             }
7543*e5337592SStefano Zampini             newp = vStartNew + (vEnd - vStart) + (p - eStart);
7544*e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7545*e5337592SStefano Zampini           } else if ((p >= fStart) && (p < fEnd)) {
7546*e5337592SStefano Zampini             /* Old faces add new faces, edges and a vertex */
7547*e5337592SStefano Zampini             for (r = 0; r < 3; ++r) {
7548*e5337592SStefano Zampini               newp = fStartNew + (p - fStart)*3 + r;
7549*e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7550*e5337592SStefano Zampini             }
7551*e5337592SStefano Zampini             for (r = 0; r < 3; ++r) {
7552*e5337592SStefano Zampini               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
7553*e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7554*e5337592SStefano Zampini             }
7555*e5337592SStefano Zampini           } else if ((p >= cStart) && (p < cEnd)) {
7556*e5337592SStefano Zampini             /* Old cells add new cells and interior faces and edges and a vertex */
7557*e5337592SStefano Zampini             for (r = 0; r < 4; ++r) {
7558*e5337592SStefano Zampini               newp = cStartNew + (p - cStart)*4 + r;
7559*e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7560*e5337592SStefano Zampini             }
7561*e5337592SStefano Zampini             for (r = 0; r < 6; ++r) {
7562*e5337592SStefano Zampini               newp = fStartNew + (fEnd - fStart)*3 + (p - cStart)*6 + r;
7563*e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7564*e5337592SStefano Zampini             }
7565*e5337592SStefano Zampini             for (r = 0; r < 4; ++r) {
7566*e5337592SStefano Zampini               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*4 + r;
7567*e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7568*e5337592SStefano Zampini             }
7569*e5337592SStefano Zampini             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + p - cStart;
7570*e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7571*e5337592SStefano Zampini           }
7572*e5337592SStefano Zampini           break;
75739b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_SIMPLEX_3D:
75746ce3c06aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
75756ce3c06aSMatthew G. Knepley             /* Interior vertices stay the same */
75766ce3c06aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
75776ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
75786ce3c06aSMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
75796ce3c06aSMatthew G. Knepley             /* Interior edges add new edges and vertex */
75806ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
75816ce3c06aSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
75826ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
75836ce3c06aSMatthew G. Knepley             }
75846ce3c06aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
75856ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
75866ce3c06aSMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
75876ce3c06aSMatthew G. Knepley             /* Hybrid edges stay the same */
75886ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
75896ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
75906ce3c06aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
75916ce3c06aSMatthew G. Knepley             /* Interior faces add new faces and edges */
75926ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
75936ce3c06aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
75946ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
75956ce3c06aSMatthew G. Knepley             }
75966ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
75976ce3c06aSMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
75986ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
75996ce3c06aSMatthew G. Knepley             }
76006ce3c06aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
76016ce3c06aSMatthew G. Knepley             /* Hybrid faces add new faces and edges */
76026ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
76036ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
76046ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
76056ce3c06aSMatthew G. Knepley             }
76066ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax);
76076ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
76086ce3c06aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
76096ce3c06aSMatthew G. Knepley             /* Interior cells add new cells, faces, and edges */
76106ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
76116ce3c06aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
76126ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
76136ce3c06aSMatthew G. Knepley             }
76146ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
76156ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
76166ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
76176ce3c06aSMatthew G. Knepley             }
76186ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart);
76196ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
762058b8852aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
76216ce3c06aSMatthew G. Knepley             /* Hybrid cells add new cells and faces */
76226ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
76236ce3c06aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
76246ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
76256ce3c06aSMatthew G. Knepley             }
76266ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
76276ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
76286ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
76296ce3c06aSMatthew G. Knepley             }
76306ce3c06aSMatthew G. Knepley           }
76316ce3c06aSMatthew G. Knepley           break;
76329b1a0e7fSLawrence Mitchell         case REFINER_HEX_3D:
76332eabf88fSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
76342eabf88fSMatthew G. Knepley             /* Old vertices stay the same */
76352eabf88fSMatthew G. Knepley             newp = vStartNew + (p - vStart);
76362eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
763719d7d790SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
76382eabf88fSMatthew G. Knepley             /* Old edges add new edges and vertex */
76392eabf88fSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
76402eabf88fSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
76412eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
76422eabf88fSMatthew G. Knepley             }
76432eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
76442eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
76452eabf88fSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
76462eabf88fSMatthew G. Knepley             /* Old faces add new faces, edges, and vertex */
76472eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
76482eabf88fSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
76492eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
76502eabf88fSMatthew G. Knepley             }
76512eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
76522eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r;
76532eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
76542eabf88fSMatthew G. Knepley             }
76552eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart);
76562eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
76572eabf88fSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
76582eabf88fSMatthew G. Knepley             /* Old cells add new cells, faces, edges, and vertex */
76592eabf88fSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
76602eabf88fSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
76612eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
76622eabf88fSMatthew G. Knepley             }
76632eabf88fSMatthew G. Knepley             for (r = 0; r < 12; ++r) {
76642eabf88fSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r;
76652eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
76662eabf88fSMatthew G. Knepley             }
76672eabf88fSMatthew G. Knepley             for (r = 0; r < 6; ++r) {
76682eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r;
76692eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
76702eabf88fSMatthew G. Knepley             }
76712eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart);
76722eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
76732eabf88fSMatthew G. Knepley           }
76742eabf88fSMatthew G. Knepley           break;
76759b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_HEX_3D:
767627fcede3SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
767727fcede3SMatthew G. Knepley             /* Interior vertices stay the same */
767827fcede3SMatthew G. Knepley             newp = vStartNew + (p - vStart);
767927fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
768027fcede3SMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
768127fcede3SMatthew G. Knepley             /* Interior edges add new edges and vertex */
768227fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
768327fcede3SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
768427fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
768527fcede3SMatthew G. Knepley             }
768627fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
768727fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
768827fcede3SMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
768927fcede3SMatthew G. Knepley             /* Hybrid edges stay the same */
769027fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax);
769127fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
769227fcede3SMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
769327fcede3SMatthew G. Knepley             /* Interior faces add new faces, edges, and vertex */
769427fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
769527fcede3SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
769627fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
769727fcede3SMatthew G. Knepley             }
769827fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
769927fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r;
770027fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
770127fcede3SMatthew G. Knepley             }
770227fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
770327fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
770427fcede3SMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
770527fcede3SMatthew G. Knepley             /* Hybrid faces add new faces and edges */
770627fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
770727fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r;
770827fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
770927fcede3SMatthew G. Knepley             }
771027fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax);
771127fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
771227fcede3SMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
771327fcede3SMatthew G. Knepley             /* Interior cells add new cells, faces, edges, and vertex */
771427fcede3SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
771527fcede3SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
771627fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
771727fcede3SMatthew G. Knepley             }
771827fcede3SMatthew G. Knepley             for (r = 0; r < 12; ++r) {
771927fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r;
772027fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
772127fcede3SMatthew G. Knepley             }
772227fcede3SMatthew G. Knepley             for (r = 0; r < 6; ++r) {
772327fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r;
772427fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
772527fcede3SMatthew G. Knepley             }
772627fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart);
772727fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
772827fcede3SMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
772927fcede3SMatthew G. Knepley             /* Hybrid cells add new cells, faces, and edges */
773027fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
773127fcede3SMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
773227fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
773327fcede3SMatthew G. Knepley             }
773427fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
773527fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r;
773627fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
773727fcede3SMatthew G. Knepley             }
773827fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax);
773927fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
774027fcede3SMatthew G. Knepley           }
774127fcede3SMatthew G. Knepley           break;
774275d3a19aSMatthew G. Knepley         default:
774375d3a19aSMatthew G. Knepley           SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
774475d3a19aSMatthew G. Knepley         }
774575d3a19aSMatthew G. Knepley       }
774675d3a19aSMatthew G. Knepley       ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr);
774775d3a19aSMatthew G. Knepley       ierr = ISDestroy(&pointIS);CHKERRQ(ierr);
774875d3a19aSMatthew G. Knepley     }
774975d3a19aSMatthew G. Knepley     ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr);
775075d3a19aSMatthew G. Knepley     ierr = ISDestroy(&valueIS);CHKERRQ(ierr);
775175d3a19aSMatthew G. Knepley     if (0) {
775275d3a19aSMatthew G. Knepley       ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
775375d3a19aSMatthew G. Knepley     }
775475d3a19aSMatthew G. Knepley   }
775575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
775675d3a19aSMatthew G. Knepley }
775775d3a19aSMatthew G. Knepley 
775875d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */
7759509c9b89SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined)
776075d3a19aSMatthew G. Knepley {
776175d3a19aSMatthew G. Knepley   DM             rdm;
776275d3a19aSMatthew G. Knepley   PetscInt      *depthSize;
776375d3a19aSMatthew G. Knepley   PetscInt       dim, depth = 0, d, pStart = 0, pEnd = 0;
776475d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
776575d3a19aSMatthew G. Knepley 
776675d3a19aSMatthew G. Knepley   PetscFunctionBegin;
776775d3a19aSMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr);
776875d3a19aSMatthew G. Knepley   ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr);
7769c73cfb54SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
7770c73cfb54SMatthew G. Knepley   ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr);
777175d3a19aSMatthew G. Knepley   /* Calculate number of new points of each depth */
777275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
77731e573d11SMatthew G. Knepley   if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement");
7774854ce69bSBarry Smith   ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr);
777575d3a19aSMatthew G. Knepley   ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr);
777675d3a19aSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
777775d3a19aSMatthew G. Knepley   /* Step 1: Set chart */
777875d3a19aSMatthew G. Knepley   for (d = 0; d <= depth; ++d) pEnd += depthSize[d];
777975d3a19aSMatthew G. Knepley   ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr);
778075d3a19aSMatthew G. Knepley   /* Step 2: Set cone/support sizes */
778175d3a19aSMatthew G. Knepley   ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
778275d3a19aSMatthew G. Knepley   /* Step 3: Setup refined DM */
778375d3a19aSMatthew G. Knepley   ierr = DMSetUp(rdm);CHKERRQ(ierr);
778475d3a19aSMatthew G. Knepley   /* Step 4: Set cones and supports */
778575d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
778675d3a19aSMatthew G. Knepley   /* Step 5: Stratify */
778775d3a19aSMatthew G. Knepley   ierr = DMPlexStratify(rdm);CHKERRQ(ierr);
77880fadad52SMatthew G. Knepley   /* Step 6: Create pointSF */
778975d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
77900fadad52SMatthew G. Knepley   /* Step 7: Set coordinates for vertices */
77910fadad52SMatthew G. Knepley   ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
779275d3a19aSMatthew G. Knepley   /* Step 8: Create labels */
779375d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
779475d3a19aSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
779575d3a19aSMatthew G. Knepley 
779675d3a19aSMatthew G. Knepley   *dmRefined = rdm;
779775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
779875d3a19aSMatthew G. Knepley }
779975d3a19aSMatthew G. Knepley 
78002389894bSMatthew G. Knepley /*@
78012389894bSMatthew G. Knepley   DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data
78022389894bSMatthew G. Knepley 
78032389894bSMatthew G. Knepley   Input Parameter:
78042389894bSMatthew G. Knepley . dm - The coarse DM
78052389894bSMatthew G. Knepley 
78062389894bSMatthew G. Knepley   Output Parameter:
78072389894bSMatthew G. Knepley . fpointIS - The IS of all the fine points which exist in the original coarse mesh
78082389894bSMatthew G. Knepley 
78092389894bSMatthew G. Knepley   Level: developer
78102389894bSMatthew G. Knepley 
78112389894bSMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS()
78122389894bSMatthew G. Knepley @*/
78132389894bSMatthew G. Knepley PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS)
78142389894bSMatthew G. Knepley {
78152389894bSMatthew G. Knepley   CellRefiner    cellRefiner;
78162389894bSMatthew G. Knepley   PetscInt      *depthSize, *fpoints;
78172389894bSMatthew G. Knepley   PetscInt       cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
78182389894bSMatthew G. Knepley   PetscInt       depth, pStart, pEnd, p, vStart, vEnd, v;
78192389894bSMatthew G. Knepley   PetscErrorCode ierr;
78202389894bSMatthew G. Knepley 
78212389894bSMatthew G. Knepley   PetscFunctionBegin;
78222389894bSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
78232389894bSMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
78242389894bSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
78252389894bSMatthew G. Knepley   ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr);
7826854ce69bSBarry Smith   ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr);
78272389894bSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
78282389894bSMatthew G. Knepley   if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
78292389894bSMatthew G. Knepley   ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr);
78302389894bSMatthew G. Knepley   for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1;
78312389894bSMatthew G. Knepley   switch (cellRefiner) {
78326c0c04f5SMatthew G. Knepley   case REFINER_SIMPLEX_1D:
78336c0c04f5SMatthew G. Knepley   case REFINER_SIMPLEX_2D:
78346c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_SIMPLEX_2D:
78356c0c04f5SMatthew G. Knepley   case REFINER_HEX_2D:
78366c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_HEX_2D:
78376c0c04f5SMatthew G. Knepley   case REFINER_SIMPLEX_3D:
78386c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_SIMPLEX_3D:
78396c0c04f5SMatthew G. Knepley   case REFINER_HEX_3D:
78406c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_HEX_3D:
78412389894bSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart);
78422389894bSMatthew G. Knepley     break;
78432389894bSMatthew G. Knepley   default:
78442389894bSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", cellRefiner);
78452389894bSMatthew G. Knepley   }
78462389894bSMatthew G. Knepley   ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr);
78472389894bSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
78482389894bSMatthew G. Knepley   PetscFunctionReturn(0);
78492389894bSMatthew G. Knepley }
78502389894bSMatthew G. Knepley 
78510e2b6761SMatthew G. Knepley /*@
78520e2b6761SMatthew G. Knepley   DMPlexSetRefinementUniform - Set the flag for uniform refinement
78530e2b6761SMatthew G. Knepley 
78540e2b6761SMatthew G. Knepley   Input Parameters:
78550e2b6761SMatthew G. Knepley + dm - The DM
78560e2b6761SMatthew G. Knepley - refinementUniform - The flag for uniform refinement
78570e2b6761SMatthew G. Knepley 
78580e2b6761SMatthew G. Knepley   Level: developer
78590e2b6761SMatthew G. Knepley 
78600e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
78610e2b6761SMatthew G. Knepley @*/
786275d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
786375d3a19aSMatthew G. Knepley {
786475d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
786575d3a19aSMatthew G. Knepley 
786675d3a19aSMatthew G. Knepley   PetscFunctionBegin;
786775d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
786875d3a19aSMatthew G. Knepley   mesh->refinementUniform = refinementUniform;
786975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
787075d3a19aSMatthew G. Knepley }
787175d3a19aSMatthew G. Knepley 
78720e2b6761SMatthew G. Knepley /*@
78730e2b6761SMatthew G. Knepley   DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement
78740e2b6761SMatthew G. Knepley 
78750e2b6761SMatthew G. Knepley   Input Parameter:
78760e2b6761SMatthew G. Knepley . dm - The DM
78770e2b6761SMatthew G. Knepley 
78780e2b6761SMatthew G. Knepley   Output Parameter:
78790e2b6761SMatthew G. Knepley . refinementUniform - The flag for uniform refinement
78800e2b6761SMatthew G. Knepley 
78810e2b6761SMatthew G. Knepley   Level: developer
78820e2b6761SMatthew G. Knepley 
78830e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
78840e2b6761SMatthew G. Knepley @*/
788575d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
788675d3a19aSMatthew G. Knepley {
788775d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
788875d3a19aSMatthew G. Knepley 
788975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
789075d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
789175d3a19aSMatthew G. Knepley   PetscValidPointer(refinementUniform,  2);
789275d3a19aSMatthew G. Knepley   *refinementUniform = mesh->refinementUniform;
789375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
789475d3a19aSMatthew G. Knepley }
789575d3a19aSMatthew G. Knepley 
78960e2b6761SMatthew G. Knepley /*@
78970e2b6761SMatthew G. Knepley   DMPlexSetRefinementLimit - Set the maximum cell volume for refinement
78980e2b6761SMatthew G. Knepley 
78990e2b6761SMatthew G. Knepley   Input Parameters:
79000e2b6761SMatthew G. Knepley + dm - The DM
79010e2b6761SMatthew G. Knepley - refinementLimit - The maximum cell volume in the refined mesh
79020e2b6761SMatthew G. Knepley 
79030e2b6761SMatthew G. Knepley   Level: developer
79040e2b6761SMatthew G. Knepley 
79050e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
79060e2b6761SMatthew G. Knepley @*/
790775d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
790875d3a19aSMatthew G. Knepley {
790975d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
791075d3a19aSMatthew G. Knepley 
791175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
791275d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
791375d3a19aSMatthew G. Knepley   mesh->refinementLimit = refinementLimit;
791475d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
791575d3a19aSMatthew G. Knepley }
791675d3a19aSMatthew G. Knepley 
79170e2b6761SMatthew G. Knepley /*@
79180e2b6761SMatthew G. Knepley   DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement
79190e2b6761SMatthew G. Knepley 
79200e2b6761SMatthew G. Knepley   Input Parameter:
79210e2b6761SMatthew G. Knepley . dm - The DM
79220e2b6761SMatthew G. Knepley 
79230e2b6761SMatthew G. Knepley   Output Parameter:
79240e2b6761SMatthew G. Knepley . refinementLimit - The maximum cell volume in the refined mesh
79250e2b6761SMatthew G. Knepley 
79260e2b6761SMatthew G. Knepley   Level: developer
79270e2b6761SMatthew G. Knepley 
79280e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
79290e2b6761SMatthew G. Knepley @*/
793075d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
793175d3a19aSMatthew G. Knepley {
793275d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
793375d3a19aSMatthew G. Knepley 
793475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
793575d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
793675d3a19aSMatthew G. Knepley   PetscValidPointer(refinementLimit,  2);
793775d3a19aSMatthew G. Knepley   /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
793875d3a19aSMatthew G. Knepley   *refinementLimit = mesh->refinementLimit;
793975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
794075d3a19aSMatthew G. Knepley }
794175d3a19aSMatthew G. Knepley 
7942b28003e6SMatthew G. Knepley /*@
7943b28003e6SMatthew G. Knepley   DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement
7944b28003e6SMatthew G. Knepley 
7945b28003e6SMatthew G. Knepley   Input Parameters:
7946b28003e6SMatthew G. Knepley + dm - The DM
7947b28003e6SMatthew G. Knepley - refinementFunc - Function giving the maximum cell volume in the refined mesh
7948b28003e6SMatthew G. Knepley 
7949b28003e6SMatthew G. Knepley   Note: The calling sequence is refinementFunc(coords, limit)
7950b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid
7951b28003e6SMatthew G. Knepley $ limit  - The maximum cell volume for a cell containing this point
7952b28003e6SMatthew G. Knepley 
7953b28003e6SMatthew G. Knepley   Level: developer
7954b28003e6SMatthew G. Knepley 
7955b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
7956b28003e6SMatthew G. Knepley @*/
7957b28003e6SMatthew G. Knepley PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *))
7958b28003e6SMatthew G. Knepley {
7959b28003e6SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
7960b28003e6SMatthew G. Knepley 
7961b28003e6SMatthew G. Knepley   PetscFunctionBegin;
7962b28003e6SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7963b28003e6SMatthew G. Knepley   mesh->refinementFunc = refinementFunc;
7964b28003e6SMatthew G. Knepley   PetscFunctionReturn(0);
7965b28003e6SMatthew G. Knepley }
7966b28003e6SMatthew G. Knepley 
7967b28003e6SMatthew G. Knepley /*@
7968b28003e6SMatthew G. Knepley   DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement
7969b28003e6SMatthew G. Knepley 
7970b28003e6SMatthew G. Knepley   Input Parameter:
7971b28003e6SMatthew G. Knepley . dm - The DM
7972b28003e6SMatthew G. Knepley 
7973b28003e6SMatthew G. Knepley   Output Parameter:
7974b28003e6SMatthew G. Knepley . refinementFunc - Function giving the maximum cell volume in the refined mesh
7975b28003e6SMatthew G. Knepley 
7976b28003e6SMatthew G. Knepley   Note: The calling sequence is refinementFunc(coords, limit)
7977b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid
7978b28003e6SMatthew G. Knepley $ limit  - The maximum cell volume for a cell containing this point
7979b28003e6SMatthew G. Knepley 
7980b28003e6SMatthew G. Knepley   Level: developer
7981b28003e6SMatthew G. Knepley 
7982b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
7983b28003e6SMatthew G. Knepley @*/
7984b28003e6SMatthew G. Knepley PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *))
7985b28003e6SMatthew G. Knepley {
7986b28003e6SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
7987b28003e6SMatthew G. Knepley 
7988b28003e6SMatthew G. Knepley   PetscFunctionBegin;
7989b28003e6SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7990b28003e6SMatthew G. Knepley   PetscValidPointer(refinementFunc,  2);
7991b28003e6SMatthew G. Knepley   *refinementFunc = mesh->refinementFunc;
7992b28003e6SMatthew G. Knepley   PetscFunctionReturn(0);
7993b28003e6SMatthew G. Knepley }
7994b28003e6SMatthew G. Knepley 
7995509c9b89SMatthew G. Knepley PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner)
799675d3a19aSMatthew G. Knepley {
79970f9259d6SMatthew G. Knepley   PetscInt       dim, cStart, cEnd, coneSize, cMax, fMax;
799875d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
799975d3a19aSMatthew G. Knepley 
800075d3a19aSMatthew G. Knepley   PetscFunctionBegin;
8001c73cfb54SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
80023478d7aaSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
80039b1a0e7fSLawrence Mitchell   if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; PetscFunctionReturn(0);}
800475d3a19aSMatthew G. Knepley   ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr);
800589b38ed4SMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, NULL, NULL);CHKERRQ(ierr);
800675d3a19aSMatthew G. Knepley   switch (dim) {
80070314a74cSLawrence Mitchell   case 1:
80080314a74cSLawrence Mitchell     switch (coneSize) {
80090314a74cSLawrence Mitchell     case 2:
80100314a74cSLawrence Mitchell       *cellRefiner = REFINER_SIMPLEX_1D;
80110314a74cSLawrence Mitchell       break;
80120314a74cSLawrence Mitchell     default:
80130314a74cSLawrence Mitchell       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
80140314a74cSLawrence Mitchell     }
80150314a74cSLawrence Mitchell     break;
801675d3a19aSMatthew G. Knepley   case 2:
801775d3a19aSMatthew G. Knepley     switch (coneSize) {
801875d3a19aSMatthew G. Knepley     case 3:
80199b1a0e7fSLawrence Mitchell       if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_2D;
80209b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_SIMPLEX_2D;
802175d3a19aSMatthew G. Knepley       break;
802275d3a19aSMatthew G. Knepley     case 4:
802389b38ed4SMatthew G. Knepley       if (cMax >= 0 && fMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_2D;
80249b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_HEX_2D;
802575d3a19aSMatthew G. Knepley       break;
802675d3a19aSMatthew G. Knepley     default:
802775d3a19aSMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
802875d3a19aSMatthew G. Knepley     }
802975d3a19aSMatthew G. Knepley     break;
8030b5da9499SMatthew G. Knepley   case 3:
8031b5da9499SMatthew G. Knepley     switch (coneSize) {
8032b5da9499SMatthew G. Knepley     case 4:
80339b1a0e7fSLawrence Mitchell       if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D;
80349b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_SIMPLEX_3D;
8035b5da9499SMatthew G. Knepley       break;
80362eabf88fSMatthew G. Knepley     case 6:
80379b1a0e7fSLawrence Mitchell       if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_3D;
80389b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_HEX_3D;
80392eabf88fSMatthew G. Knepley       break;
8040b5da9499SMatthew G. Knepley     default:
8041b5da9499SMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
8042b5da9499SMatthew G. Knepley     }
8043b5da9499SMatthew G. Knepley     break;
804475d3a19aSMatthew G. Knepley   default:
804575d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim);
804675d3a19aSMatthew G. Knepley   }
804775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
804875d3a19aSMatthew G. Knepley }
8049