xref: /petsc/src/dm/impls/plex/plexrefine.c (revision 492b8470e37ee7982c59840057d4b461f24ec0ce)
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     }
14524c234d2SMatthew G. Knepley     if (sum > 1.0e-10) {*inside = PETSC_FALSE; break;}
14680389061SMatthew G. Knepley     break;
1476c0c04f5SMatthew G. Knepley   case REFINER_HEX_2D:
14824c234d2SMatthew G. Knepley     for (d = 0; d < 2; ++d) if ((point[d] < -1.00000000001) || (point[d] > 1.000000000001)) {*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;
186e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_2D:
187e5337592SStefano Zampini     depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */
188e5337592SStefano Zampini     depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart);         /* Every face is split into 2 faces and 3 faces are added for each cell */
189e5337592SStefano Zampini     depthSize[2] = 3*(cEnd - cStart);                             /* Every cell split into 3 cells */
190e5337592SStefano 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;
229e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_3D:
230e5337592SStefano Zampini     depthSize[0] = vEnd - vStart + fEnd - fStart + eEnd - eStart + cEnd - cStart; /* Add a vertex on every face, edge and cell */
231e5337592SStefano 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 */
232e5337592SStefano Zampini     depthSize[2] = 3*(fEnd - fStart) + 6*(cEnd - cStart);                         /* Every face is split into 3 faces and 6 faces are added for each cell */
233e5337592SStefano Zampini     depthSize[3] = 4*(cEnd - cStart);                                             /* Every cell split into 4 cells */
234e5337592SStefano 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 
278e5337592SStefano Zampini /* Return the interior edge number connecting the midpoints of the triangle edges r
279e5337592SStefano Zampini    and r+1 in the transitive closure for triangle orientation o */
280e5337592SStefano 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 }
283e5337592SStefano 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 
287e5337592SStefano Zampini /* Return the interior edge number connecting the midpoint of the triangle edge r
288e5337592SStefano Zampini    (in the transitive closure) and the vertex in the interior of the face for triangle orientation o */
289e5337592SStefano Zampini PETSC_STATIC_INLINE PetscInt GetTriInteriorEdge_Static(PetscInt o, PetscInt r) {
290e5337592SStefano Zampini   return (o < 0 ? 2-(o+r) : o+r)%3;
291e5337592SStefano Zampini }
292e5337592SStefano Zampini PETSC_STATIC_INLINE PetscInt GetTriInteriorEdgeInverse_Static(PetscInt o, PetscInt s) {
293e5337592SStefano Zampini   return (o < 0 ? 2-(o+s) : 3+s-o)%3;
294e5337592SStefano 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;
397e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_2D:
398e5337592SStefano Zampini     /* All cells have 4 faces */
399e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
400e5337592SStefano Zampini       for (r = 0; r < 3; ++r) {
401e5337592SStefano Zampini         const PetscInt newp = (c - cStart)*3 + r;
402e5337592SStefano Zampini 
403e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
404e5337592SStefano Zampini       }
405e5337592SStefano Zampini     }
406e5337592SStefano Zampini     /* Split faces have 2 vertices and the same cells as the parent */
407e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
408e5337592SStefano Zampini       for (r = 0; r < 2; ++r) {
409e5337592SStefano Zampini         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
410e5337592SStefano Zampini         PetscInt       size;
411e5337592SStefano Zampini 
412e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
413e5337592SStefano Zampini         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
414e5337592SStefano Zampini         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
415e5337592SStefano Zampini       }
416e5337592SStefano Zampini     }
417e5337592SStefano Zampini     /* Interior faces have 2 vertices and 2 cells */
418e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
419e5337592SStefano Zampini       for (r = 0; r < 3; ++r) {
420e5337592SStefano Zampini         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
421e5337592SStefano Zampini 
422e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
423e5337592SStefano Zampini         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
424e5337592SStefano Zampini       }
425e5337592SStefano Zampini     }
426e5337592SStefano Zampini     /* Old vertices have identical supports */
427e5337592SStefano Zampini     for (v = vStart; v < vEnd; ++v) {
428e5337592SStefano Zampini       const PetscInt newp = vStartNew + (v - vStart);
429e5337592SStefano Zampini       PetscInt       size;
430e5337592SStefano Zampini 
431e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
432e5337592SStefano Zampini       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
433e5337592SStefano Zampini     }
434e5337592SStefano Zampini     /* Split-face vertices have cells + 2 supports */
435e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
436e5337592SStefano Zampini       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
437e5337592SStefano Zampini       PetscInt       size;
438e5337592SStefano Zampini 
439e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
440e5337592SStefano Zampini       ierr = DMPlexSetSupportSize(rdm, newp, size + 2);CHKERRQ(ierr);
441e5337592SStefano Zampini     }
442e5337592SStefano Zampini     /* Interior vertices have 3 supports */
443e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
444e5337592SStefano Zampini       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
445e5337592SStefano Zampini 
446e5337592SStefano Zampini       ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr);
447e5337592SStefano Zampini     }
448e5337592SStefano 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 */
719e5337592SStefano 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 */
860e5337592SStefano 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;
941e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_3D:
942e5337592SStefano Zampini     /* All cells have 6 faces */
943e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
944e5337592SStefano Zampini       for (r = 0; r < 4; ++r) {
945e5337592SStefano Zampini         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
946e5337592SStefano Zampini 
947e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
948e5337592SStefano Zampini       }
949e5337592SStefano Zampini     }
950e5337592SStefano Zampini     /* Split faces have 4 edges and the same cells as the parent */
951e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
952e5337592SStefano Zampini       for (r = 0; r < 3; ++r) {
953e5337592SStefano Zampini         const PetscInt newp = fStartNew + (f - fStart)*3 + r;
954e5337592SStefano Zampini         PetscInt       size;
955e5337592SStefano Zampini 
956e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
957e5337592SStefano Zampini         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
958e5337592SStefano Zampini         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
959e5337592SStefano Zampini       }
960e5337592SStefano Zampini     }
961e5337592SStefano Zampini     /* Interior cell faces have 4 edges and 2 cells */
962e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
963e5337592SStefano Zampini       for (r = 0; r < 6; ++r) {
964e5337592SStefano Zampini         const PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + r;
965e5337592SStefano Zampini 
966e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
967e5337592SStefano Zampini         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
968e5337592SStefano Zampini       }
969e5337592SStefano Zampini     }
970e5337592SStefano Zampini     /* Split edges have 2 vertices and the same faces */
971e5337592SStefano Zampini     for (e = eStart; e < eEnd; ++e) {
972e5337592SStefano Zampini       for (r = 0; r < 2; ++r) {
973e5337592SStefano Zampini         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
974e5337592SStefano Zampini         PetscInt       size;
975e5337592SStefano Zampini 
976e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
977e5337592SStefano Zampini         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
978e5337592SStefano Zampini         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
979e5337592SStefano Zampini       }
980e5337592SStefano Zampini     }
981e5337592SStefano Zampini     /* Face edges have 2 vertices and 2 + cell faces supports */
982e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
983e5337592SStefano Zampini       for (r = 0; r < 3; ++r) {
984e5337592SStefano Zampini         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
985e5337592SStefano Zampini         PetscInt        size;
986e5337592SStefano Zampini 
987e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
988e5337592SStefano Zampini         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
989e5337592SStefano Zampini         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
990e5337592SStefano Zampini       }
991e5337592SStefano Zampini     }
992e5337592SStefano Zampini     /* Interior cell edges have 2 vertices and 3 faces */
993e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
994e5337592SStefano Zampini       for (r = 0; r < 4; ++r) {
995e5337592SStefano Zampini         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r;
996e5337592SStefano Zampini 
997e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
998e5337592SStefano Zampini         ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr);
999e5337592SStefano Zampini       }
1000e5337592SStefano Zampini     }
1001e5337592SStefano Zampini     /* Old vertices have identical supports */
1002e5337592SStefano Zampini     for (v = vStart; v < vEnd; ++v) {
1003e5337592SStefano Zampini       const PetscInt newp = vStartNew + (v - vStart);
1004e5337592SStefano Zampini       PetscInt       size;
1005e5337592SStefano Zampini 
1006e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
1007e5337592SStefano Zampini       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
1008e5337592SStefano Zampini     }
1009e5337592SStefano Zampini     /* Edge vertices have 2 + faces supports */
1010e5337592SStefano Zampini     for (e = eStart; e < eEnd; ++e) {
1011e5337592SStefano Zampini       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
1012e5337592SStefano Zampini       PetscInt       size;
1013e5337592SStefano Zampini 
1014e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
1015e5337592SStefano Zampini       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
1016e5337592SStefano Zampini     }
1017e5337592SStefano Zampini     /* Face vertices have 3 + cells supports */
1018e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
1019e5337592SStefano Zampini       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart;
1020e5337592SStefano Zampini       PetscInt       size;
1021e5337592SStefano Zampini 
1022e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
1023e5337592SStefano Zampini       ierr = DMPlexSetSupportSize(rdm, newp, 3 + size);CHKERRQ(ierr);
1024e5337592SStefano Zampini     }
1025e5337592SStefano Zampini     /* Interior cell vertices have 4 supports */
1026e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
1027e5337592SStefano Zampini       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + fEnd - fStart + c - cStart;
1028e5337592SStefano Zampini 
1029e5337592SStefano Zampini       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
1030e5337592SStefano Zampini     }
1031e5337592SStefano 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;
1567e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_2D:
1568e5337592SStefano Zampini     /*
1569e5337592SStefano Zampini      2
1570e5337592SStefano Zampini      |\
1571e5337592SStefano Zampini      | \
1572e5337592SStefano Zampini      |  \
1573e5337592SStefano Zampini      |   \
1574e5337592SStefano Zampini      | C  \
1575e5337592SStefano Zampini      |     \
1576e5337592SStefano Zampini      2      1
1577e5337592SStefano Zampini      |\    / \
1578e5337592SStefano Zampini      | 2  1   \
1579e5337592SStefano Zampini      |  \/     \
1580e5337592SStefano Zampini      |   |      \
1581e5337592SStefano Zampini      |A  |   B   \
1582e5337592SStefano Zampini      |   0        \
1583e5337592SStefano Zampini      |   |         \
1584e5337592SStefano Zampini      0---0----------1
1585e5337592SStefano Zampini      */
1586e5337592SStefano Zampini     /* All cells have 4 faces */
1587e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
1588e5337592SStefano Zampini       const PetscInt  newp = cStartNew + (c - cStart)*3;
1589e5337592SStefano Zampini       const PetscInt *cone, *ornt;
1590e5337592SStefano Zampini       PetscInt        coneNew[4], orntNew[4];
1591e5337592SStefano Zampini 
1592e5337592SStefano Zampini       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1593e5337592SStefano Zampini       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1594e5337592SStefano Zampini       /* A quad */
1595e5337592SStefano Zampini       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
1596e5337592SStefano Zampini       orntNew[0] = ornt[0];
1597e5337592SStefano Zampini       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
1598e5337592SStefano Zampini       orntNew[1] = 0;
1599e5337592SStefano Zampini       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
1600e5337592SStefano Zampini       orntNew[2] = -2;
1601e5337592SStefano Zampini       coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
1602e5337592SStefano Zampini       orntNew[3] = ornt[2];
1603e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
1604e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
1605e5337592SStefano Zampini #if 1
1606e5337592SStefano 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);
1607e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
1608e5337592SStefano 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);
1609e5337592SStefano Zampini       }
1610e5337592SStefano Zampini #endif
1611e5337592SStefano Zampini       /* B quad */
1612e5337592SStefano Zampini       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
1613e5337592SStefano Zampini       orntNew[0] = ornt[0];
1614e5337592SStefano Zampini       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
1615e5337592SStefano Zampini       orntNew[1] = ornt[1];
1616e5337592SStefano Zampini       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
1617e5337592SStefano Zampini       orntNew[2] = 0;
1618e5337592SStefano Zampini       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
1619e5337592SStefano Zampini       orntNew[3] = -2;
1620e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
1621e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
1622e5337592SStefano Zampini #if 1
1623e5337592SStefano 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);
1624e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
1625e5337592SStefano 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);
1626e5337592SStefano Zampini       }
1627e5337592SStefano Zampini #endif
1628e5337592SStefano Zampini       /* C quad */
1629e5337592SStefano Zampini       coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
1630e5337592SStefano Zampini       orntNew[0] = ornt[1];
1631e5337592SStefano Zampini       coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
1632e5337592SStefano Zampini       orntNew[1] = ornt[2];
1633e5337592SStefano Zampini       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
1634e5337592SStefano Zampini       orntNew[2] = 0;
1635e5337592SStefano Zampini       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
1636e5337592SStefano Zampini       orntNew[3] = -2;
1637e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
1638e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
1639e5337592SStefano Zampini #if 1
1640e5337592SStefano 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);
1641e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
1642e5337592SStefano 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);
1643e5337592SStefano Zampini       }
1644e5337592SStefano Zampini #endif
1645e5337592SStefano Zampini     }
1646e5337592SStefano Zampini     /* Split faces have 2 vertices and the same cells as the parent */
1647e5337592SStefano Zampini     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1648e5337592SStefano Zampini     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
1649e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
1650e5337592SStefano Zampini       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
1651e5337592SStefano Zampini 
1652e5337592SStefano Zampini       for (r = 0; r < 2; ++r) {
1653e5337592SStefano Zampini         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1654e5337592SStefano Zampini         const PetscInt *cone, *ornt, *support;
1655e5337592SStefano Zampini         PetscInt        coneNew[2], coneSize, c, supportSize, s;
1656e5337592SStefano Zampini 
1657e5337592SStefano Zampini         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
1658e5337592SStefano Zampini         coneNew[0]       = vStartNew + (cone[0] - vStart);
1659e5337592SStefano Zampini         coneNew[1]       = vStartNew + (cone[1] - vStart);
1660e5337592SStefano Zampini         coneNew[(r+1)%2] = newv;
1661e5337592SStefano Zampini         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1662e5337592SStefano Zampini #if 1
1663e5337592SStefano Zampini         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1664e5337592SStefano Zampini         for (p = 0; p < 2; ++p) {
1665e5337592SStefano 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);
1666e5337592SStefano Zampini         }
1667e5337592SStefano Zampini #endif
1668e5337592SStefano Zampini         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
1669e5337592SStefano Zampini         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
1670e5337592SStefano Zampini         for (s = 0; s < supportSize; ++s) {
1671e5337592SStefano Zampini           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
1672e5337592SStefano Zampini           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1673e5337592SStefano Zampini           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
1674e5337592SStefano Zampini           for (c = 0; c < coneSize; ++c) {
1675e5337592SStefano Zampini             if (cone[c] == f) break;
1676e5337592SStefano Zampini           }
1677e5337592SStefano Zampini           supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
1678e5337592SStefano Zampini         }
1679e5337592SStefano Zampini         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
1680e5337592SStefano Zampini #if 1
1681e5337592SStefano Zampini         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1682e5337592SStefano Zampini         for (p = 0; p < supportSize; ++p) {
1683e5337592SStefano 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);
1684e5337592SStefano Zampini         }
1685e5337592SStefano Zampini #endif
1686e5337592SStefano Zampini       }
1687e5337592SStefano Zampini     }
1688e5337592SStefano Zampini     /* Interior faces have 2 vertices and 2 cells */
1689e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
1690e5337592SStefano Zampini       const PetscInt *cone;
1691e5337592SStefano Zampini 
1692e5337592SStefano Zampini       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1693e5337592SStefano Zampini       for (r = 0; r < 3; ++r) {
1694e5337592SStefano Zampini         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
1695e5337592SStefano Zampini         PetscInt       coneNew[2];
1696e5337592SStefano Zampini         PetscInt       supportNew[2];
1697e5337592SStefano Zampini 
1698e5337592SStefano Zampini         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
1699e5337592SStefano Zampini         coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd    - fStart) + (c - cStart);
1700e5337592SStefano Zampini         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1701e5337592SStefano Zampini #if 1
1702e5337592SStefano Zampini         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1703e5337592SStefano Zampini         for (p = 0; p < 2; ++p) {
1704e5337592SStefano 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);
1705e5337592SStefano Zampini         }
1706e5337592SStefano Zampini #endif
1707e5337592SStefano Zampini         supportNew[0] = (c - cStart)*3 + r%3;
1708e5337592SStefano Zampini         supportNew[1] = (c - cStart)*3 + (r+1)%3;
1709e5337592SStefano Zampini         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1710e5337592SStefano Zampini #if 1
1711e5337592SStefano Zampini         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1712e5337592SStefano Zampini         for (p = 0; p < 2; ++p) {
1713e5337592SStefano 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);
1714e5337592SStefano Zampini         }
1715e5337592SStefano Zampini #endif
1716e5337592SStefano Zampini       }
1717e5337592SStefano Zampini     }
1718e5337592SStefano Zampini     /* Old vertices have identical supports */
1719e5337592SStefano Zampini     for (v = vStart; v < vEnd; ++v) {
1720e5337592SStefano Zampini       const PetscInt  newp = vStartNew + (v - vStart);
1721e5337592SStefano Zampini       const PetscInt *support, *cone;
1722e5337592SStefano Zampini       PetscInt        size, s;
1723e5337592SStefano Zampini 
1724e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
1725e5337592SStefano Zampini       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
1726e5337592SStefano Zampini       for (s = 0; s < size; ++s) {
1727e5337592SStefano Zampini         PetscInt r = 0;
1728e5337592SStefano Zampini 
1729e5337592SStefano Zampini         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1730e5337592SStefano Zampini         if (cone[1] == v) r = 1;
1731e5337592SStefano Zampini         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
1732e5337592SStefano Zampini       }
1733e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
1734e5337592SStefano Zampini #if 1
1735e5337592SStefano Zampini       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
1736e5337592SStefano Zampini       for (p = 0; p < size; ++p) {
1737e5337592SStefano 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);
1738e5337592SStefano Zampini       }
1739e5337592SStefano Zampini #endif
1740e5337592SStefano Zampini     }
1741e5337592SStefano Zampini     /* Split-face vertices have cells + 2 supports */
1742e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
1743e5337592SStefano Zampini       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
1744e5337592SStefano Zampini       const PetscInt *cone, *support;
1745e5337592SStefano Zampini       PetscInt        size, s;
1746e5337592SStefano Zampini 
1747e5337592SStefano Zampini       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
1748e5337592SStefano Zampini       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
1749e5337592SStefano Zampini       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
1750e5337592SStefano Zampini       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
1751e5337592SStefano Zampini       for (s = 0; s < size; ++s) {
1752e5337592SStefano Zampini         PetscInt r = 0;
1753e5337592SStefano Zampini 
1754e5337592SStefano Zampini         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1755e5337592SStefano Zampini         if      (cone[1] == f) r = 1;
1756e5337592SStefano Zampini         else if (cone[2] == f) r = 2;
1757e5337592SStefano Zampini         supportRef[2+s+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
1758e5337592SStefano Zampini       }
1759e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
1760e5337592SStefano Zampini #if 1
1761e5337592SStefano Zampini       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
1762e5337592SStefano Zampini       for (p = 0; p < 2+size; ++p) {
1763e5337592SStefano 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);
1764e5337592SStefano Zampini       }
1765e5337592SStefano Zampini #endif
1766e5337592SStefano Zampini     }
1767e5337592SStefano Zampini     /* Interior vertices vertices have 3 supports */
1768e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
1769e5337592SStefano Zampini       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
1770e5337592SStefano Zampini 
1771e5337592SStefano Zampini       supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
1772e5337592SStefano Zampini       supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
1773e5337592SStefano Zampini       supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
1774e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
1775e5337592SStefano Zampini     }
1776e5337592SStefano Zampini     ierr = PetscFree(supportRef);CHKERRQ(ierr);
1777e5337592SStefano 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;
1821efb27101SLisandro Dalcin       orntNew[2] = -2;
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;
1834efb27101SLisandro Dalcin       orntNew[0] = 0;
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;
1840efb27101SLisandro Dalcin       orntNew[3] = -2;
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;
1853efb27101SLisandro Dalcin       orntNew[1] = 0;
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 
1918efb27101SLisandro Dalcin 	if (r==1 || r==2) {
1919efb27101SLisandro Dalcin           coneNew[0] = vStartNew + (vEnd - vStart) + (fEnd    - fStart) + (c - cStart);
1920efb27101SLisandro Dalcin           coneNew[1] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
1921efb27101SLisandro Dalcin 	} else {
192275d3a19aSMatthew G. Knepley           coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
192375d3a19aSMatthew G. Knepley           coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd    - fStart) + (c - cStart);
1924efb27101SLisandro Dalcin 	}
192575d3a19aSMatthew G. Knepley 	ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
192675d3a19aSMatthew G. Knepley #if 1
192775d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
192875d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
192975d3a19aSMatthew 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);
193075d3a19aSMatthew G. Knepley         }
193175d3a19aSMatthew G. Knepley #endif
193275d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
193375d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
193475d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
193575d3a19aSMatthew G. Knepley #if 1
193675d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
193775d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
193875d3a19aSMatthew 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);
193975d3a19aSMatthew G. Knepley         }
194075d3a19aSMatthew G. Knepley #endif
194175d3a19aSMatthew G. Knepley       }
194275d3a19aSMatthew G. Knepley     }
194375d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
194475d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
194575d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
194675d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
194775d3a19aSMatthew G. Knepley       PetscInt        size, s;
194875d3a19aSMatthew G. Knepley 
194975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
195075d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
195175d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
195275d3a19aSMatthew G. Knepley         PetscInt r = 0;
195375d3a19aSMatthew G. Knepley 
195475d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
195575d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
195675d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
195775d3a19aSMatthew G. Knepley       }
195875d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
195975d3a19aSMatthew G. Knepley #if 1
196075d3a19aSMatthew 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);
196175d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
196275d3a19aSMatthew 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);
196375d3a19aSMatthew G. Knepley       }
196475d3a19aSMatthew G. Knepley #endif
196575d3a19aSMatthew G. Knepley     }
196675d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
196775d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
196875d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
196975d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
197075d3a19aSMatthew G. Knepley       PetscInt        size, s;
197175d3a19aSMatthew G. Knepley 
197275d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
197375d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
197475d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
197575d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
197675d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
197775d3a19aSMatthew G. Knepley         PetscInt r = 0;
197875d3a19aSMatthew G. Knepley 
197975d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
198075d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
198175d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
198275d3a19aSMatthew G. Knepley         else if (cone[3] == f) r = 3;
198375d3a19aSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r;
198475d3a19aSMatthew G. Knepley       }
198575d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
198675d3a19aSMatthew G. Knepley #if 1
198775d3a19aSMatthew 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);
198875d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
198975d3a19aSMatthew 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);
199075d3a19aSMatthew G. Knepley       }
199175d3a19aSMatthew G. Knepley #endif
199275d3a19aSMatthew G. Knepley     }
199375d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
199475d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
199575d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
199675d3a19aSMatthew G. Knepley       PetscInt       supportNew[4];
199775d3a19aSMatthew G. Knepley 
199875d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
199975d3a19aSMatthew G. Knepley         supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
200075d3a19aSMatthew G. Knepley       }
200175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
200275d3a19aSMatthew G. Knepley     }
2003da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
200475d3a19aSMatthew G. Knepley     break;
20059b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
200675d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
200775d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
200875d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
200975d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
2010149f48fdSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr);
201175d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
201275d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
201375d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
201475d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
201575d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
201675d3a19aSMatthew G. Knepley 
201775d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
201875d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
201975d3a19aSMatthew G. Knepley       /* A triangle */
202075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
202175d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
202275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
202375d3a19aSMatthew G. Knepley       orntNew[1] = -2;
202475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
202575d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
202675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
202775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
202875d3a19aSMatthew G. Knepley #if 1
2029149f48fdSMatthew 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);
203075d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2031149f48fdSMatthew 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);
203275d3a19aSMatthew G. Knepley       }
203375d3a19aSMatthew G. Knepley #endif
203475d3a19aSMatthew G. Knepley       /* B triangle */
203575d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
203675d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
203775d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
203875d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
203975d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
204075d3a19aSMatthew G. Knepley       orntNew[2] = -2;
204175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
204275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
204375d3a19aSMatthew G. Knepley #if 1
2044a97b51b8SMatthew 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);
204575d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2046a97b51b8SMatthew 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);
204775d3a19aSMatthew G. Knepley       }
204875d3a19aSMatthew G. Knepley #endif
204975d3a19aSMatthew G. Knepley       /* C triangle */
205075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
205175d3a19aSMatthew G. Knepley       orntNew[0] = -2;
205275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
205375d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
205475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
205575d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
205675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
205775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
205875d3a19aSMatthew G. Knepley #if 1
2059a97b51b8SMatthew 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);
206075d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2061a97b51b8SMatthew 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);
206275d3a19aSMatthew G. Knepley       }
206375d3a19aSMatthew G. Knepley #endif
206475d3a19aSMatthew G. Knepley       /* D triangle */
206575d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
206675d3a19aSMatthew G. Knepley       orntNew[0] = 0;
206775d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
206875d3a19aSMatthew G. Knepley       orntNew[1] = 0;
206975d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
207075d3a19aSMatthew G. Knepley       orntNew[2] = 0;
207175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
207275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
207375d3a19aSMatthew G. Knepley #if 1
2074a97b51b8SMatthew 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);
207575d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2076a97b51b8SMatthew 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);
207775d3a19aSMatthew G. Knepley       }
207875d3a19aSMatthew G. Knepley #endif
207975d3a19aSMatthew G. Knepley     }
208075d3a19aSMatthew G. Knepley     /*
208175d3a19aSMatthew G. Knepley      2----3----3
208275d3a19aSMatthew G. Knepley      |         |
208375d3a19aSMatthew G. Knepley      |    B    |
208475d3a19aSMatthew G. Knepley      |         |
208575d3a19aSMatthew G. Knepley      0----4--- 1
208675d3a19aSMatthew G. Knepley      |         |
208775d3a19aSMatthew G. Knepley      |    A    |
208875d3a19aSMatthew G. Knepley      |         |
208975d3a19aSMatthew G. Knepley      0----2----1
209075d3a19aSMatthew G. Knepley      */
209175d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
209275d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
209375d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
209475d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
2095ea00e70eSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4], r;
209675d3a19aSMatthew G. Knepley 
209775d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
209875d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2099ea00e70eSMatthew G. Knepley       r    = (ornt[0] < 0 ? 1 : 0);
210075d3a19aSMatthew G. Knepley       /* A quad */
2101ea00e70eSMatthew G. Knepley       coneNew[0]   = fStartNew + (cone[0] - fStart)*2 + r;
210275d3a19aSMatthew G. Knepley       orntNew[0]   = ornt[0];
2103ea00e70eSMatthew G. Knepley       coneNew[1]   = fStartNew + (cone[1] - fStart)*2 + r;
210475d3a19aSMatthew G. Knepley       orntNew[1]   = ornt[1];
2105ea00e70eSMatthew G. Knepley       coneNew[2+r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax);
2106ea00e70eSMatthew G. Knepley       orntNew[2+r] = 0;
2107ea00e70eSMatthew G. Knepley       coneNew[3-r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
2108ea00e70eSMatthew G. Knepley       orntNew[3-r] = 0;
210975d3a19aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
211075d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
211175d3a19aSMatthew G. Knepley #if 1
211275d3a19aSMatthew 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);
211375d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
211475d3a19aSMatthew 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);
211575d3a19aSMatthew G. Knepley       }
211675d3a19aSMatthew G. Knepley #endif
211775d3a19aSMatthew G. Knepley       /* B quad */
2118ea00e70eSMatthew G. Knepley       coneNew[0]   = fStartNew + (cone[0] - fStart)*2 + 1-r;
211975d3a19aSMatthew G. Knepley       orntNew[0]   = ornt[0];
2120ea00e70eSMatthew G. Knepley       coneNew[1]   = fStartNew + (cone[1] - fStart)*2 + 1-r;
212175d3a19aSMatthew G. Knepley       orntNew[1]   = ornt[1];
2122ea00e70eSMatthew G. Knepley       coneNew[2+r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
2123ea00e70eSMatthew G. Knepley       orntNew[2+r] = 0;
2124ea00e70eSMatthew G. Knepley       coneNew[3-r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax);
2125ea00e70eSMatthew G. Knepley       orntNew[3-r] = 0;
212675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
212775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
212875d3a19aSMatthew G. Knepley #if 1
212975d3a19aSMatthew 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);
213075d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
213175d3a19aSMatthew 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);
213275d3a19aSMatthew G. Knepley       }
213375d3a19aSMatthew G. Knepley #endif
213475d3a19aSMatthew G. Knepley     }
213575d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
213675d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2137854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
213875d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
213975d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
214075d3a19aSMatthew G. Knepley 
214175d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
214275d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
2143297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
214475d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
214575d3a19aSMatthew G. Knepley 
214675d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
214775d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
214875d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
214975d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
215075d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
215175d3a19aSMatthew G. Knepley #if 1
215275d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
215375d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
215475d3a19aSMatthew 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);
215575d3a19aSMatthew G. Knepley         }
215675d3a19aSMatthew G. Knepley #endif
215775d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
215875d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
215975d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
216075d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
216175d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2162297d2bf4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2163ea00e70eSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == f) break;
2164ea00e70eSMatthew G. Knepley           if (support[s] >= cMax) {
2165ea00e70eSMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r);
2166ea00e70eSMatthew G. Knepley           } else {
2167297d2bf4SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
216875d3a19aSMatthew G. Knepley           }
216975d3a19aSMatthew G. Knepley         }
217075d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
217175d3a19aSMatthew G. Knepley #if 1
217275d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
217375d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
217475d3a19aSMatthew 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);
217575d3a19aSMatthew G. Knepley         }
217675d3a19aSMatthew G. Knepley #endif
217775d3a19aSMatthew G. Knepley       }
217875d3a19aSMatthew G. Knepley     }
217975d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
218075d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
218175d3a19aSMatthew G. Knepley       const PetscInt *cone;
218275d3a19aSMatthew G. Knepley 
218375d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
218475d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
218575d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
218675d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
218775d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
218875d3a19aSMatthew G. Knepley 
218975d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
219075d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
219175d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
219275d3a19aSMatthew G. Knepley #if 1
219375d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
219475d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
219575d3a19aSMatthew 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);
219675d3a19aSMatthew G. Knepley         }
219775d3a19aSMatthew G. Knepley #endif
219875d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
219975d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
220075d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
220175d3a19aSMatthew G. Knepley #if 1
220275d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
220375d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
220475d3a19aSMatthew 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);
220575d3a19aSMatthew G. Knepley         }
220675d3a19aSMatthew G. Knepley #endif
220775d3a19aSMatthew G. Knepley       }
220875d3a19aSMatthew G. Knepley     }
220975d3a19aSMatthew G. Knepley     /* Interior hybrid faces have 2 vertices and the same cells */
221075d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
221175d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
2212ea00e70eSMatthew G. Knepley       const PetscInt *cone, *ornt;
221375d3a19aSMatthew G. Knepley       const PetscInt *support;
221475d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
221575d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
221675d3a19aSMatthew G. Knepley       PetscInt        size, s, r;
221775d3a19aSMatthew G. Knepley 
221875d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
221975d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
222075d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
222175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
222275d3a19aSMatthew G. Knepley #if 1
222375d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
222475d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
222575d3a19aSMatthew 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);
222675d3a19aSMatthew G. Knepley       }
222775d3a19aSMatthew G. Knepley #endif
222875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
222975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
223075d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
223175d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2232ea00e70eSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
223375d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r) {
223475d3a19aSMatthew G. Knepley           if (cone[r+2] == f) break;
223575d3a19aSMatthew G. Knepley         }
2236ea00e70eSMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r);
223775d3a19aSMatthew G. Knepley       }
223875d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
223975d3a19aSMatthew G. Knepley #if 1
224075d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
224175d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
224275d3a19aSMatthew 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);
224375d3a19aSMatthew G. Knepley       }
224475d3a19aSMatthew G. Knepley #endif
224575d3a19aSMatthew G. Knepley     }
224675d3a19aSMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
224775d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
224875d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
224975d3a19aSMatthew G. Knepley       const PetscInt *cone;
225075d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
225175d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
225275d3a19aSMatthew G. Knepley 
225375d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
225475d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
225575d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
225675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
225775d3a19aSMatthew G. Knepley #if 1
225875d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
225975d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
226075d3a19aSMatthew 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);
226175d3a19aSMatthew G. Knepley       }
226275d3a19aSMatthew G. Knepley #endif
226375d3a19aSMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
226475d3a19aSMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
226575d3a19aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
226675d3a19aSMatthew G. Knepley #if 1
226775d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
226875d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
226975d3a19aSMatthew 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);
227075d3a19aSMatthew G. Knepley       }
227175d3a19aSMatthew G. Knepley #endif
227275d3a19aSMatthew G. Knepley     }
227375d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
227475d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
227575d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
227675d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
227775d3a19aSMatthew G. Knepley       PetscInt        size, s;
227875d3a19aSMatthew G. Knepley 
227975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
228075d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
228175d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
228275d3a19aSMatthew G. Knepley         if (support[s] >= fMax) {
228375d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax);
228475d3a19aSMatthew G. Knepley         } else {
228575d3a19aSMatthew G. Knepley           PetscInt r = 0;
228675d3a19aSMatthew G. Knepley 
228775d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
228875d3a19aSMatthew G. Knepley           if (cone[1] == v) r = 1;
228975d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
229075d3a19aSMatthew G. Knepley         }
229175d3a19aSMatthew G. Knepley       }
229275d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
229375d3a19aSMatthew G. Knepley #if 1
229475d3a19aSMatthew 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);
229575d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
229675d3a19aSMatthew 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);
229775d3a19aSMatthew G. Knepley       }
229875d3a19aSMatthew G. Knepley #endif
229975d3a19aSMatthew G. Knepley     }
230075d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
230175d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
230275d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
230375d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
230475d3a19aSMatthew G. Knepley       PetscInt        size, newSize = 2, s;
230575d3a19aSMatthew G. Knepley 
230675d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
230775d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
230875d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
230975d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
231075d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
231175d3a19aSMatthew G. Knepley         PetscInt r = 0;
231275d3a19aSMatthew G. Knepley 
231375d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
231475d3a19aSMatthew G. Knepley         if (support[s] >= cMax) {
231575d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax);
231675d3a19aSMatthew G. Knepley 
231775d3a19aSMatthew G. Knepley           newSize += 1;
231875d3a19aSMatthew G. Knepley         } else {
231975d3a19aSMatthew G. Knepley           if      (cone[1] == f) r = 1;
232075d3a19aSMatthew G. Knepley           else if (cone[2] == f) r = 2;
232175d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
232275d3a19aSMatthew G. Knepley           supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r;
232375d3a19aSMatthew G. Knepley 
232475d3a19aSMatthew G. Knepley           newSize += 2;
232575d3a19aSMatthew G. Knepley         }
232675d3a19aSMatthew G. Knepley       }
232775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
232875d3a19aSMatthew G. Knepley #if 1
232975d3a19aSMatthew 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);
233075d3a19aSMatthew G. Knepley       for (p = 0; p < newSize; ++p) {
233175d3a19aSMatthew 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);
233275d3a19aSMatthew G. Knepley       }
233375d3a19aSMatthew G. Knepley #endif
233475d3a19aSMatthew G. Knepley     }
233575d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
233675d3a19aSMatthew G. Knepley     break;
23379b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
2338a97b51b8SMatthew G. Knepley     /* Hybrid Hex 2D */
2339a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
2340a97b51b8SMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
2341a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
2342a97b51b8SMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
2343a97b51b8SMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr);
2344a97b51b8SMatthew G. Knepley     /* Interior cells have 4 faces */
2345a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
2346a97b51b8SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
2347a97b51b8SMatthew G. Knepley       const PetscInt *cone, *ornt;
2348a97b51b8SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
2349a97b51b8SMatthew G. Knepley 
2350a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2351a97b51b8SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2352a97b51b8SMatthew G. Knepley       /* A quad */
2353a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2354a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2355a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 0;
2356a97b51b8SMatthew G. Knepley       orntNew[1] = 0;
2357a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 3;
2358a97b51b8SMatthew G. Knepley       orntNew[2] = -2;
2359a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
2360a97b51b8SMatthew G. Knepley       orntNew[3] = ornt[3];
2361a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2362a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2363a97b51b8SMatthew G. Knepley #if 1
2364a97b51b8SMatthew 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);
2365a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2366a97b51b8SMatthew 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);
2367a97b51b8SMatthew G. Knepley       }
2368a97b51b8SMatthew G. Knepley #endif
2369a97b51b8SMatthew G. Knepley       /* B quad */
2370a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2371a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2372a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2373a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2374a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 1;
2375a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
2376a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 0;
2377a97b51b8SMatthew G. Knepley       orntNew[3] = -2;
2378a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2379a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2380a97b51b8SMatthew G. Knepley #if 1
2381a97b51b8SMatthew 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);
2382a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2383a97b51b8SMatthew 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);
2384a97b51b8SMatthew G. Knepley       }
2385a97b51b8SMatthew G. Knepley #endif
2386a97b51b8SMatthew G. Knepley       /* C quad */
2387a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 1;
2388a97b51b8SMatthew G. Knepley       orntNew[0] = -2;
2389a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2390a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2391a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
2392a97b51b8SMatthew G. Knepley       orntNew[2] = ornt[2];
2393a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 2;
2394a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
2395a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2396a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2397a97b51b8SMatthew G. Knepley #if 1
2398a97b51b8SMatthew 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);
2399a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2400a97b51b8SMatthew 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);
2401a97b51b8SMatthew G. Knepley       }
2402a97b51b8SMatthew G. Knepley #endif
2403a97b51b8SMatthew G. Knepley       /* D quad */
2404a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 3;
2405a97b51b8SMatthew G. Knepley       orntNew[0] = 0;
2406a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 2;
2407a97b51b8SMatthew G. Knepley       orntNew[1] = -2;
2408a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
2409a97b51b8SMatthew G. Knepley       orntNew[2] = ornt[2];
2410a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
2411a97b51b8SMatthew G. Knepley       orntNew[3] = ornt[3];
2412a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2413a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2414a97b51b8SMatthew G. Knepley #if 1
2415a97b51b8SMatthew 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);
2416a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2417a97b51b8SMatthew 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);
2418a97b51b8SMatthew G. Knepley       }
2419a97b51b8SMatthew G. Knepley #endif
2420a97b51b8SMatthew G. Knepley     }
2421a97b51b8SMatthew G. Knepley     /*
2422a97b51b8SMatthew G. Knepley      2----3----3
2423a97b51b8SMatthew G. Knepley      |         |
2424a97b51b8SMatthew G. Knepley      |    B    |
2425a97b51b8SMatthew G. Knepley      |         |
2426a97b51b8SMatthew G. Knepley      0----4--- 1
2427a97b51b8SMatthew G. Knepley      |         |
2428a97b51b8SMatthew G. Knepley      |    A    |
2429a97b51b8SMatthew G. Knepley      |         |
2430a97b51b8SMatthew G. Knepley      0----2----1
2431a97b51b8SMatthew G. Knepley      */
2432a97b51b8SMatthew G. Knepley     /* Hybrid cells have 4 faces */
2433a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
2434a97b51b8SMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
2435a97b51b8SMatthew G. Knepley       const PetscInt *cone, *ornt;
2436a97b51b8SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
2437a97b51b8SMatthew G. Knepley 
2438a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2439a97b51b8SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2440a97b51b8SMatthew G. Knepley       /* A quad */
2441a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2442a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2443a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2444a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2445a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax);
2446a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
2447a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (fEnd    - fMax) + (c - cMax);
2448a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
2449a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2450a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2451a97b51b8SMatthew G. Knepley #if 1
2452a97b51b8SMatthew 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);
2453a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2454a97b51b8SMatthew 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);
2455a97b51b8SMatthew G. Knepley       }
2456a97b51b8SMatthew G. Knepley #endif
2457a97b51b8SMatthew G. Knepley       /* B quad */
2458a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2459a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2460a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2461a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2462a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (fEnd    - fMax) + (c - cMax);
2463a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
2464a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax);
2465a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
2466a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2467a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2468a97b51b8SMatthew G. Knepley #if 1
2469a97b51b8SMatthew 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);
2470a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2471a97b51b8SMatthew 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);
2472a97b51b8SMatthew G. Knepley       }
2473a97b51b8SMatthew G. Knepley #endif
2474a97b51b8SMatthew G. Knepley     }
2475a97b51b8SMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
2476a97b51b8SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2477854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
2478a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
2479a97b51b8SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
2480a97b51b8SMatthew G. Knepley 
2481a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
2482a97b51b8SMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
2483a97b51b8SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
2484a97b51b8SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
2485a97b51b8SMatthew G. Knepley 
2486a97b51b8SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2487a97b51b8SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
2488a97b51b8SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
2489a97b51b8SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
2490a97b51b8SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2491a97b51b8SMatthew G. Knepley #if 1
2492a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2493a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2494a97b51b8SMatthew 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);
2495a97b51b8SMatthew G. Knepley         }
2496a97b51b8SMatthew G. Knepley #endif
2497a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2498a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2499a97b51b8SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2500a97b51b8SMatthew G. Knepley           if (support[s] >= cMax) {
2501a97b51b8SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
2502a97b51b8SMatthew G. Knepley           } else {
2503a97b51b8SMatthew G. Knepley             ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2504a97b51b8SMatthew G. Knepley             ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2505a97b51b8SMatthew G. Knepley             ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2506a97b51b8SMatthew G. Knepley             for (c = 0; c < coneSize; ++c) {
2507a97b51b8SMatthew G. Knepley               if (cone[c] == f) break;
2508a97b51b8SMatthew G. Knepley             }
2509a97b51b8SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
2510a97b51b8SMatthew G. Knepley           }
2511a97b51b8SMatthew G. Knepley         }
2512a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2513a97b51b8SMatthew G. Knepley #if 1
2514a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2515a97b51b8SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2516a97b51b8SMatthew 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);
2517a97b51b8SMatthew G. Knepley         }
2518a97b51b8SMatthew G. Knepley #endif
2519a97b51b8SMatthew G. Knepley       }
2520a97b51b8SMatthew G. Knepley     }
2521a97b51b8SMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
2522a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
2523a97b51b8SMatthew G. Knepley       const PetscInt *cone;
2524a97b51b8SMatthew G. Knepley 
2525a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2526a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2527a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
2528a97b51b8SMatthew G. Knepley         PetscInt       coneNew[2], supportNew[2];
2529a97b51b8SMatthew G. Knepley 
2530a97b51b8SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2531a97b51b8SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fMax    - fStart) + (c - cStart);
2532a97b51b8SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2533a97b51b8SMatthew G. Knepley #if 1
2534a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2535a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2536a97b51b8SMatthew 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);
2537a97b51b8SMatthew G. Knepley         }
2538a97b51b8SMatthew G. Knepley #endif
2539a97b51b8SMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
2540a97b51b8SMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
2541a97b51b8SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2542a97b51b8SMatthew G. Knepley #if 1
2543a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2544a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2545a97b51b8SMatthew 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);
2546a97b51b8SMatthew G. Knepley         }
2547a97b51b8SMatthew G. Knepley #endif
2548a97b51b8SMatthew G. Knepley       }
2549a97b51b8SMatthew G. Knepley     }
2550a97b51b8SMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
2551a97b51b8SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
2552a97b51b8SMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
2553a97b51b8SMatthew G. Knepley       const PetscInt *cone, *support;
2554a97b51b8SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
2555a97b51b8SMatthew G. Knepley       PetscInt        size, s, r;
2556a97b51b8SMatthew G. Knepley 
2557a97b51b8SMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2558a97b51b8SMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
2559a97b51b8SMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
2560a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2561a97b51b8SMatthew G. Knepley #if 1
2562a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2563a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2564a97b51b8SMatthew 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);
2565a97b51b8SMatthew G. Knepley       }
2566a97b51b8SMatthew G. Knepley #endif
2567a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
2568a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2569a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2570a97b51b8SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2571a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r) {
2572a97b51b8SMatthew G. Knepley           if (cone[r+2] == f) break;
2573a97b51b8SMatthew G. Knepley         }
2574a97b51b8SMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
2575a97b51b8SMatthew G. Knepley       }
2576a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2577a97b51b8SMatthew G. Knepley #if 1
2578a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2579a97b51b8SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2580a97b51b8SMatthew 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);
2581a97b51b8SMatthew G. Knepley       }
2582a97b51b8SMatthew G. Knepley #endif
2583a97b51b8SMatthew G. Knepley     }
2584a97b51b8SMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
2585a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
2586a97b51b8SMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
2587a97b51b8SMatthew G. Knepley       const PetscInt *cone;
2588a97b51b8SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
2589a97b51b8SMatthew G. Knepley 
2590a97b51b8SMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2591a97b51b8SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
2592a97b51b8SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
2593a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2594a97b51b8SMatthew G. Knepley #if 1
2595a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2596a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2597a97b51b8SMatthew 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);
2598a97b51b8SMatthew G. Knepley       }
2599a97b51b8SMatthew G. Knepley #endif
2600a97b51b8SMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
2601a97b51b8SMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
2602a97b51b8SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2603a97b51b8SMatthew G. Knepley #if 1
2604a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2605a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2606a97b51b8SMatthew 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);
2607a97b51b8SMatthew G. Knepley       }
2608a97b51b8SMatthew G. Knepley #endif
2609a97b51b8SMatthew G. Knepley     }
2610a97b51b8SMatthew G. Knepley     /* Old vertices have identical supports */
2611a97b51b8SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
2612a97b51b8SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
2613a97b51b8SMatthew G. Knepley       const PetscInt *support, *cone;
2614a97b51b8SMatthew G. Knepley       PetscInt        size, s;
2615a97b51b8SMatthew G. Knepley 
2616a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
2617a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
2618a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2619a97b51b8SMatthew G. Knepley         if (support[s] >= fMax) {
2620a97b51b8SMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax);
2621a97b51b8SMatthew G. Knepley         } else {
2622a97b51b8SMatthew G. Knepley           PetscInt r = 0;
2623a97b51b8SMatthew G. Knepley 
2624a97b51b8SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2625a97b51b8SMatthew G. Knepley           if (cone[1] == v) r = 1;
2626a97b51b8SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
2627a97b51b8SMatthew G. Knepley         }
2628a97b51b8SMatthew G. Knepley       }
2629a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2630a97b51b8SMatthew G. Knepley #if 1
2631a97b51b8SMatthew 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);
2632a97b51b8SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2633a97b51b8SMatthew 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);
2634a97b51b8SMatthew G. Knepley       }
2635a97b51b8SMatthew G. Knepley #endif
2636a97b51b8SMatthew G. Knepley     }
2637a97b51b8SMatthew G. Knepley     /* Face vertices have 2 + cells supports */
2638a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
2639a97b51b8SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
2640a97b51b8SMatthew G. Knepley       const PetscInt *cone, *support;
2641a97b51b8SMatthew G. Knepley       PetscInt        size, s;
2642a97b51b8SMatthew G. Knepley 
2643a97b51b8SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
2644a97b51b8SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2645a97b51b8SMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
2646a97b51b8SMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
2647a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2648a97b51b8SMatthew G. Knepley         PetscInt r = 0;
2649a97b51b8SMatthew G. Knepley 
2650a97b51b8SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2651a97b51b8SMatthew G. Knepley         if (support[s] >= cMax) {
2652a97b51b8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax);
2653a97b51b8SMatthew G. Knepley         } else {
2654a97b51b8SMatthew G. Knepley           if      (cone[1] == f) r = 1;
2655a97b51b8SMatthew G. Knepley           else if (cone[2] == f) r = 2;
2656a97b51b8SMatthew G. Knepley           else if (cone[3] == f) r = 3;
2657a97b51b8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r;
2658a97b51b8SMatthew G. Knepley         }
2659a97b51b8SMatthew G. Knepley       }
2660a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2661a97b51b8SMatthew G. Knepley #if 1
2662a97b51b8SMatthew 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);
2663a97b51b8SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
2664a97b51b8SMatthew 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);
2665a97b51b8SMatthew G. Knepley       }
2666a97b51b8SMatthew G. Knepley #endif
2667a97b51b8SMatthew G. Knepley     }
2668a97b51b8SMatthew G. Knepley     /* Cell vertices have 4 supports */
2669a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
2670a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
2671a97b51b8SMatthew G. Knepley       PetscInt       supportNew[4];
2672a97b51b8SMatthew G. Knepley 
2673a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2674a97b51b8SMatthew G. Knepley         supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
2675a97b51b8SMatthew G. Knepley       }
2676a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2677a97b51b8SMatthew G. Knepley     }
2678a97b51b8SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
2679a97b51b8SMatthew G. Knepley     break;
26809b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
2681b5da9499SMatthew G. Knepley     /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
2682b5da9499SMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
2683b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2684b5da9499SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
2685b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
2686b5da9499SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
2687b5da9499SMatthew G. Knepley 
2688b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2689b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2690b5da9499SMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
2691518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
2692b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2693518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
2694b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2695518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
2696b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2697b5da9499SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
2698b5da9499SMatthew G. Knepley       orntNew[3] = 0;
2699b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2700b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2701b5da9499SMatthew G. Knepley #if 1
2702b5da9499SMatthew 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);
2703b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2704b5da9499SMatthew 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);
2705b5da9499SMatthew G. Knepley       }
2706b5da9499SMatthew G. Knepley #endif
2707b5da9499SMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
2708518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
2709b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2710518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
2711b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2712b5da9499SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
2713b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2714518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
2715b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2716b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2717b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2718b5da9499SMatthew G. Knepley #if 1
2719b5da9499SMatthew 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);
2720b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2721b5da9499SMatthew 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);
2722b5da9499SMatthew G. Knepley       }
2723b5da9499SMatthew G. Knepley #endif
2724b5da9499SMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
2725518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
2726b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2727b5da9499SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
2728b5da9499SMatthew G. Knepley       orntNew[1] = 0;
2729518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
2730b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2731518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
2732b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2733b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2734b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2735b5da9499SMatthew G. Knepley #if 1
2736b5da9499SMatthew 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);
2737b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2738b5da9499SMatthew 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);
2739b5da9499SMatthew G. Knepley       }
2740b5da9499SMatthew G. Knepley #endif
2741b5da9499SMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
2742b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
2743b5da9499SMatthew G. Knepley       orntNew[0] = 0;
2744518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
2745b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2746518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
2747b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2748518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
2749b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2750b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2751b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2752b5da9499SMatthew G. Knepley #if 1
2753b5da9499SMatthew 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);
2754b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2755b5da9499SMatthew 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);
2756b5da9499SMatthew G. Knepley       }
2757b5da9499SMatthew G. Knepley #endif
27583fe31fa2SToby Isaac       /* A' tetrahedron: {c, d, a, f} */
2759b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
2760b5da9499SMatthew G. Knepley       orntNew[0] = -3;
2761fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
2762e5337592SStefano Zampini       orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0);
2763fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
2764fac4ab25SMatthew G. Knepley       orntNew[2] = 0;
2765fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
2766fac4ab25SMatthew G. Knepley       orntNew[3] = 2;
2767b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
2768b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
2769b5da9499SMatthew G. Knepley #if 1
2770b5da9499SMatthew 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);
2771b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2772b5da9499SMatthew 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);
2773b5da9499SMatthew G. Knepley       }
2774b5da9499SMatthew G. Knepley #endif
2775b5da9499SMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
2776b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
27773fe31fa2SToby Isaac       orntNew[0] = -2;
27783fe31fa2SToby Isaac       coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3;
2779e5337592SStefano Zampini       orntNew[1] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 1)+1) : GetTriMidEdge_Static(ornt[3], 1);
27803fe31fa2SToby Isaac       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
2781b5da9499SMatthew G. Knepley       orntNew[2] = 0;
27823fe31fa2SToby Isaac       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
27833fe31fa2SToby Isaac       orntNew[3] = 0;
2784b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
2785b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
2786b5da9499SMatthew G. Knepley #if 1
2787b5da9499SMatthew 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);
2788b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2789b5da9499SMatthew 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);
2790b5da9499SMatthew G. Knepley       }
2791b5da9499SMatthew G. Knepley #endif
27923fe31fa2SToby Isaac       /* C' tetrahedron: {f, a, c, b} */
27933fe31fa2SToby Isaac       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
27943fe31fa2SToby Isaac       orntNew[0] = -2;
27953fe31fa2SToby Isaac       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
27963fe31fa2SToby Isaac       orntNew[1] = -2;
27973fe31fa2SToby Isaac       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
27983fe31fa2SToby Isaac       orntNew[2] = -1;
27993fe31fa2SToby Isaac       coneNew[3] = fStartNew + (cone[0] - fStart)*4 + 3;
2800e5337592SStefano Zampini       orntNew[3] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2);
2801b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
2802b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
2803b5da9499SMatthew G. Knepley #if 1
2804b5da9499SMatthew 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);
2805b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2806b5da9499SMatthew 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);
2807b5da9499SMatthew G. Knepley       }
2808b5da9499SMatthew G. Knepley #endif
28093fe31fa2SToby Isaac       /* D' tetrahedron: {f, a, e, d} */
28103fe31fa2SToby Isaac       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
28113fe31fa2SToby Isaac       orntNew[0] = -2;
2812fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
28133fe31fa2SToby Isaac       orntNew[1] = -1;
28143fe31fa2SToby Isaac       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
28153fe31fa2SToby Isaac       orntNew[2] = -2;
28163fe31fa2SToby Isaac       coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3;
2817e5337592SStefano Zampini       orntNew[3] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 1)+1) : GetTriMidEdge_Static(ornt[1], 1);
2818b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
2819b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
2820b5da9499SMatthew G. Knepley #if 1
2821b5da9499SMatthew 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);
2822b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2823b5da9499SMatthew 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);
2824b5da9499SMatthew G. Knepley       }
2825b5da9499SMatthew G. Knepley #endif
2826b5da9499SMatthew G. Knepley     }
2827b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
2828b5da9499SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2829854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
2830b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
2831b5da9499SMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
2832b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
2833b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
2834b5da9499SMatthew G. Knepley 
2835b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2836b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
2837b5da9499SMatthew G. Knepley       /* A triangle */
2838b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
2839b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2840b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
2841b5da9499SMatthew G. Knepley       orntNew[1] = -2;
2842b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
2843b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2844b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2845b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2846b5da9499SMatthew G. Knepley #if 1
2847b5da9499SMatthew 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);
2848b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2849b5da9499SMatthew 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);
2850b5da9499SMatthew G. Knepley       }
2851b5da9499SMatthew G. Knepley #endif
2852b5da9499SMatthew G. Knepley       /* B triangle */
2853b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
2854b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2855b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
2856b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2857b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
2858b5da9499SMatthew G. Knepley       orntNew[2] = -2;
2859b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2860b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2861b5da9499SMatthew G. Knepley #if 1
2862b5da9499SMatthew 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);
2863b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2864b5da9499SMatthew 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);
2865b5da9499SMatthew G. Knepley       }
2866b5da9499SMatthew G. Knepley #endif
2867b5da9499SMatthew G. Knepley       /* C triangle */
2868b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
2869b5da9499SMatthew G. Knepley       orntNew[0] = -2;
2870b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
2871b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2872b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
2873b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2874b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2875b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2876b5da9499SMatthew G. Knepley #if 1
2877b5da9499SMatthew 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);
2878b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2879b5da9499SMatthew 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);
2880b5da9499SMatthew G. Knepley       }
2881b5da9499SMatthew G. Knepley #endif
2882b5da9499SMatthew G. Knepley       /* D triangle */
2883b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
2884b5da9499SMatthew G. Knepley       orntNew[0] = 0;
2885b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
2886b5da9499SMatthew G. Knepley       orntNew[1] = 0;
2887b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
2888b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2889b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2890b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2891b5da9499SMatthew G. Knepley #if 1
2892b5da9499SMatthew 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);
2893b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2894b5da9499SMatthew 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);
2895b5da9499SMatthew G. Knepley       }
2896b5da9499SMatthew G. Knepley #endif
2897b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2898b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2899b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2900b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2901219f7b90SMatthew G. Knepley           PetscInt subf;
2902b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2903b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2904b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2905b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
2906b5da9499SMatthew G. Knepley             if (cone[c] == f) break;
2907b5da9499SMatthew G. Knepley           }
2908219f7b90SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
2909219f7b90SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
2910b5da9499SMatthew G. Knepley         }
2911b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
2912b5da9499SMatthew G. Knepley #if 1
29139ddff745SMatthew 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);
2914b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2915b5da9499SMatthew 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);
2916b5da9499SMatthew G. Knepley         }
2917b5da9499SMatthew G. Knepley #endif
2918b5da9499SMatthew G. Knepley       }
2919b5da9499SMatthew G. Knepley     }
2920b5da9499SMatthew G. Knepley     /* Interior faces have 3 edges and 2 cells */
2921b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2922b5da9499SMatthew G. Knepley       PetscInt        newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8;
2923b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
2924b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
2925b5da9499SMatthew G. Knepley       PetscInt        supportNew[2];
2926b5da9499SMatthew G. Knepley 
2927b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2928b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2929b5da9499SMatthew G. Knepley       /* Face A: {c, a, d} */
2930e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
2931b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
2932e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
2933b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
2934e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2);
2935b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
2936b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2937b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2938b5da9499SMatthew G. Knepley #if 1
2939b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2940b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2941b5da9499SMatthew 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);
2942b5da9499SMatthew G. Knepley       }
2943b5da9499SMatthew G. Knepley #endif
2944b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
2945b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
2946b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2947b5da9499SMatthew G. Knepley #if 1
2948b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2949b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2950b5da9499SMatthew 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);
2951b5da9499SMatthew G. Knepley       }
2952b5da9499SMatthew G. Knepley #endif
2953b5da9499SMatthew G. Knepley       ++newp;
2954b5da9499SMatthew G. Knepley       /* Face B: {a, b, e} */
2955e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
2956b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
2957e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0);
2958b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
2959e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
2960b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
2961b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2962b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2963b5da9499SMatthew G. Knepley #if 1
29644bb260e2SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2965b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2966b5da9499SMatthew 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);
2967b5da9499SMatthew G. Knepley       }
2968b5da9499SMatthew G. Knepley #endif
2969b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
2970b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
2971b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2972b5da9499SMatthew G. Knepley #if 1
2973b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2974b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2975b5da9499SMatthew 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);
2976b5da9499SMatthew G. Knepley       }
2977b5da9499SMatthew G. Knepley #endif
2978b5da9499SMatthew G. Knepley       ++newp;
2979b5da9499SMatthew G. Knepley       /* Face C: {c, f, b} */
2980e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
2981b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
2982e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
2983b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
2984e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1);
2985b5da9499SMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
2986b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2987b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2988b5da9499SMatthew G. Knepley #if 1
2989b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2990b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2991b5da9499SMatthew 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);
2992b5da9499SMatthew G. Knepley       }
2993b5da9499SMatthew G. Knepley #endif
2994b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
2995b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2996b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2997b5da9499SMatthew G. Knepley #if 1
2998b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2999b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3000b5da9499SMatthew 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);
3001b5da9499SMatthew G. Knepley       }
3002b5da9499SMatthew G. Knepley #endif
3003b5da9499SMatthew G. Knepley       ++newp;
3004b5da9499SMatthew G. Knepley       /* Face D: {d, e, f} */
3005e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0);
3006b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
3007e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
3008b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
3009e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
3010b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
3011b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3012b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3013b5da9499SMatthew G. Knepley #if 1
3014b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3015b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
3016b5da9499SMatthew 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);
3017b5da9499SMatthew G. Knepley       }
3018b5da9499SMatthew G. Knepley #endif
3019b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
3020b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
3021b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3022b5da9499SMatthew G. Knepley #if 1
3023b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3024b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3025b5da9499SMatthew 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);
3026b5da9499SMatthew G. Knepley       }
3027b5da9499SMatthew G. Knepley #endif
3028b5da9499SMatthew G. Knepley       ++newp;
3029b5da9499SMatthew G. Knepley       /* Face E: {d, f, a} */
3030e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
3031b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
3032b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
30334bb260e2SMatthew G. Knepley       orntNew[1] = -2;
3034e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
3035b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
3036b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3037b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3038b5da9499SMatthew G. Knepley #if 1
3039b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3040b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
3041b5da9499SMatthew 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);
3042b5da9499SMatthew G. Knepley       }
3043b5da9499SMatthew G. Knepley #endif
3044b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
3045b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
3046b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3047b5da9499SMatthew G. Knepley #if 1
3048b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3049b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3050b5da9499SMatthew 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);
3051b5da9499SMatthew G. Knepley       }
3052b5da9499SMatthew G. Knepley #endif
3053b5da9499SMatthew G. Knepley       ++newp;
3054b5da9499SMatthew G. Knepley       /* Face F: {c, a, f} */
3055e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
3056b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
3057b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
30584bb260e2SMatthew G. Knepley       orntNew[1] = 0;
3059e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
30602baf2947SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
3061b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3062b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3063b5da9499SMatthew G. Knepley #if 1
3064b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3065b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
3066b5da9499SMatthew 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);
3067b5da9499SMatthew G. Knepley       }
3068b5da9499SMatthew G. Knepley #endif
3069b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
3070b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
3071b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3072b5da9499SMatthew G. Knepley #if 1
3073b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3074b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3075b5da9499SMatthew 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);
3076b5da9499SMatthew G. Knepley       }
3077b5da9499SMatthew G. Knepley #endif
3078b5da9499SMatthew G. Knepley       ++newp;
3079b5da9499SMatthew G. Knepley       /* Face G: {e, a, f} */
3080e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
3081b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
3082b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
3083fac4ab25SMatthew G. Knepley       orntNew[1] = 0;
3084e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
3085b5da9499SMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
3086b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3087b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3088b5da9499SMatthew G. Knepley #if 1
3089b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3090b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
3091b5da9499SMatthew 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);
3092b5da9499SMatthew G. Knepley       }
3093b5da9499SMatthew G. Knepley #endif
3094b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
3095b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
3096b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3097b5da9499SMatthew G. Knepley #if 1
3098b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3099b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3100b5da9499SMatthew 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);
3101b5da9499SMatthew G. Knepley       }
3102b5da9499SMatthew G. Knepley #endif
3103b5da9499SMatthew G. Knepley       ++newp;
3104b5da9499SMatthew G. Knepley       /* Face H: {a, b, f} */
3105e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
3106b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
3107e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
3108b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
3109b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
31104bb260e2SMatthew G. Knepley       orntNew[2] = -2;
3111b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3112b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3113b5da9499SMatthew G. Knepley #if 1
3114b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3115b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
3116b5da9499SMatthew 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);
3117b5da9499SMatthew G. Knepley       }
3118b5da9499SMatthew G. Knepley #endif
3119b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
3120b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
3121b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3122b5da9499SMatthew G. Knepley #if 1
3123b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3124b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3125b5da9499SMatthew 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);
3126b5da9499SMatthew G. Knepley       }
3127b5da9499SMatthew G. Knepley #endif
3128b5da9499SMatthew G. Knepley       ++newp;
3129b5da9499SMatthew G. Knepley     }
3130b5da9499SMatthew G. Knepley     /* Split Edges have 2 vertices and the same faces as the parent */
3131b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
3132b5da9499SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
3133b5da9499SMatthew G. Knepley 
3134b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
3135b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
3136b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
3137b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
3138b5da9499SMatthew G. Knepley 
3139b5da9499SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
3140b5da9499SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
3141b5da9499SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
3142b5da9499SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
3143b5da9499SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3144b5da9499SMatthew G. Knepley #if 1
3145b5da9499SMatthew 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);
3146b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
3147b5da9499SMatthew 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);
3148b5da9499SMatthew G. Knepley         }
3149b5da9499SMatthew G. Knepley #endif
3150b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
3151b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
3152b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
3153b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
3154b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
3155b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
3156b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
3157b5da9499SMatthew G. Knepley             if (cone[c] == e) break;
3158b5da9499SMatthew G. Knepley           }
3159b5da9499SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
3160b5da9499SMatthew G. Knepley         }
3161b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
3162b5da9499SMatthew G. Knepley #if 1
3163b5da9499SMatthew 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);
3164b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
3165b5da9499SMatthew 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);
3166b5da9499SMatthew G. Knepley         }
3167b5da9499SMatthew G. Knepley #endif
3168b5da9499SMatthew G. Knepley       }
3169b5da9499SMatthew G. Knepley     }
317086f0afeeSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
3171b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
3172b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
3173b5da9499SMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
3174b5da9499SMatthew G. Knepley 
3175b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
3176b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
3177b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
3178b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
3179b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
3180b5da9499SMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
3181b5da9499SMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
3182b5da9499SMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
3183b5da9499SMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
3184b5da9499SMatthew G. Knepley 
3185b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
3186b5da9499SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
3187b5da9499SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
3188b5da9499SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3189b5da9499SMatthew G. Knepley #if 1
3190b5da9499SMatthew 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);
3191b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
3192b5da9499SMatthew 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);
3193b5da9499SMatthew G. Knepley         }
3194b5da9499SMatthew G. Knepley #endif
3195b5da9499SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
3196b5da9499SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
3197b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
3198b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
3199b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
3200b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
3201b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
320286f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
3203e5337592SStefano Zampini           er = GetTriMidEdgeInverse_Static(ornt[c], r);
3204b5da9499SMatthew G. Knepley           if (er == eint[c]) {
3205b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
3206b5da9499SMatthew G. Knepley           } else {
3207b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
3208b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
3209b5da9499SMatthew G. Knepley           }
3210b5da9499SMatthew G. Knepley         }
3211b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
3212b5da9499SMatthew G. Knepley #if 1
3213b5da9499SMatthew 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);
3214b5da9499SMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
3215b5da9499SMatthew 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);
3216b5da9499SMatthew G. Knepley         }
3217b5da9499SMatthew G. Knepley #endif
3218b5da9499SMatthew G. Knepley       }
3219b5da9499SMatthew G. Knepley     }
3220b5da9499SMatthew G. Knepley     /* Interior edges have 2 vertices and 4 faces */
3221b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
3222b5da9499SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
3223b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
32244a40f731SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
3225b5da9499SMatthew G. Knepley 
3226b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
3227b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
3228b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
322942525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
3230b5da9499SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
3231b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
323242525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
3233b5da9499SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
3234b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3235b5da9499SMatthew G. Knepley #if 1
3236b5da9499SMatthew 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);
3237b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3238b5da9499SMatthew 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);
3239b5da9499SMatthew G. Knepley       }
3240b5da9499SMatthew G. Knepley #endif
3241b5da9499SMatthew G. Knepley       supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
3242b5da9499SMatthew G. Knepley       supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
3243b5da9499SMatthew G. Knepley       supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
3244b5da9499SMatthew G. Knepley       supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
3245b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3246b5da9499SMatthew G. Knepley #if 1
3247b5da9499SMatthew 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);
3248b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3249b5da9499SMatthew 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);
3250b5da9499SMatthew G. Knepley       }
3251b5da9499SMatthew G. Knepley #endif
3252b5da9499SMatthew G. Knepley     }
3253b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
3254b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
3255b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
3256b5da9499SMatthew G. Knepley       const PetscInt *support, *cone;
3257b5da9499SMatthew G. Knepley       PetscInt        size, s;
3258b5da9499SMatthew G. Knepley 
3259b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
3260b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
3261b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
3262b5da9499SMatthew G. Knepley         PetscInt r = 0;
3263b5da9499SMatthew G. Knepley 
3264b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
3265b5da9499SMatthew G. Knepley         if (cone[1] == v) r = 1;
3266b5da9499SMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
3267b5da9499SMatthew G. Knepley       }
3268b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
3269b5da9499SMatthew G. Knepley #if 1
3270b5da9499SMatthew 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);
3271b5da9499SMatthew G. Knepley       for (p = 0; p < size; ++p) {
3272b5da9499SMatthew 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);
3273b5da9499SMatthew G. Knepley       }
3274b5da9499SMatthew G. Knepley #endif
3275b5da9499SMatthew G. Knepley     }
3276b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + face*2 + 0/1 supports */
3277b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
3278b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
3279b5da9499SMatthew G. Knepley       const PetscInt *cone, *support;
3280b5da9499SMatthew G. Knepley       PetscInt       *star = NULL, starSize, cellSize = 0, coneSize, size, s;
3281b5da9499SMatthew G. Knepley 
3282b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
3283b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
3284b5da9499SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
3285b5da9499SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
3286b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
3287b5da9499SMatthew G. Knepley         PetscInt r = 0;
3288b5da9499SMatthew G. Knepley 
3289b5da9499SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
3290b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
3291b5da9499SMatthew G. Knepley         for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
3292b5da9499SMatthew G. Knepley         supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
3293b5da9499SMatthew G. Knepley         supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
3294b5da9499SMatthew G. Knepley       }
3295b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
3296b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
3297b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
3298b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
3299b5da9499SMatthew G. Knepley 
3300b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
3301b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
3302b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
3303b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
3304b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
330542525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
3306b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
3307b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
3308b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
330942525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
331042525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
3311b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);}
3312b5da9499SMatthew G. Knepley         }
3313b5da9499SMatthew G. Knepley       }
3314b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
3315b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
3316b5da9499SMatthew G. Knepley #if 1
3317b5da9499SMatthew 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);
3318b5da9499SMatthew G. Knepley       for (p = 0; p < 2+size*2+cellSize; ++p) {
3319b5da9499SMatthew 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);
3320b5da9499SMatthew G. Knepley       }
3321b5da9499SMatthew G. Knepley #endif
3322b5da9499SMatthew G. Knepley     }
3323b5da9499SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
3324b5da9499SMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
3325b5da9499SMatthew G. Knepley     break;
33269b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
33276ce3c06aSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
33286ce3c06aSMatthew G. Knepley     /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
33296ce3c06aSMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
33306ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
33316ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
33326ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
33336ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
33346ce3c06aSMatthew G. Knepley 
33356ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
33366ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
33376ce3c06aSMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
33386ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
33396ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
33406ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
33416ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
33426ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
33436ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
33446ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
33456ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
33466ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
33476ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
33486ce3c06aSMatthew G. Knepley #if 1
33496ce3c06aSMatthew 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);
33506ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
33516ce3c06aSMatthew 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);
33526ce3c06aSMatthew G. Knepley       }
33536ce3c06aSMatthew G. Knepley #endif
33546ce3c06aSMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
33556ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
33566ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
33576ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
33586ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
33596ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
33606ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
33616ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
33626ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
33636ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
33646ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
33656ce3c06aSMatthew G. Knepley #if 1
33666ce3c06aSMatthew 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);
33676ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
33686ce3c06aSMatthew 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);
33696ce3c06aSMatthew G. Knepley       }
33706ce3c06aSMatthew G. Knepley #endif
33716ce3c06aSMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
33726ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
33736ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
33746ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
33756ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
33766ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
33776ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
33786ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
33796ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
33806ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
33816ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
33826ce3c06aSMatthew G. Knepley #if 1
33836ce3c06aSMatthew 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);
33846ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
33856ce3c06aSMatthew 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);
33866ce3c06aSMatthew G. Knepley       }
33876ce3c06aSMatthew G. Knepley #endif
33886ce3c06aSMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
33896ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
33906ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
33916ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
33926ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
33936ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
33946ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
33956ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
33966ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
33976ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
33986ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
33996ce3c06aSMatthew G. Knepley #if 1
34006ce3c06aSMatthew 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);
34016ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
34026ce3c06aSMatthew 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);
34036ce3c06aSMatthew G. Knepley       }
34046ce3c06aSMatthew G. Knepley #endif
34056ce3c06aSMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
34066ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
34076ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
34089ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
3409e5337592SStefano Zampini       orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0);
34109ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
34119ddff745SMatthew G. Knepley       orntNew[2] = 0;
34129ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
34139ddff745SMatthew G. Knepley       orntNew[3] = 2;
34146ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
34156ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
34166ce3c06aSMatthew G. Knepley #if 1
34176ce3c06aSMatthew 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);
34186ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
34196ce3c06aSMatthew 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);
34206ce3c06aSMatthew G. Knepley       }
34216ce3c06aSMatthew G. Knepley #endif
34226ce3c06aSMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
34236ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
34246ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
34259ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
34269ddff745SMatthew G. Knepley       orntNew[1] = 1;
34279ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
34286ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
34299ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
3430e5337592SStefano Zampini       orntNew[3] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 0)+1) : GetTriMidEdge_Static(ornt[3], 0);
34316ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
34326ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
34336ce3c06aSMatthew G. Knepley #if 1
34346ce3c06aSMatthew 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);
34356ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
34366ce3c06aSMatthew 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);
34376ce3c06aSMatthew G. Knepley       }
34386ce3c06aSMatthew G. Knepley #endif
34396ce3c06aSMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
34406ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
34416ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
34429ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
3443e5337592SStefano Zampini       orntNew[1] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2);
34449ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
34459ddff745SMatthew G. Knepley       orntNew[2] = -3;
34469ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
34479ddff745SMatthew G. Knepley       orntNew[3] = -2;
34486ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
34496ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
34506ce3c06aSMatthew G. Knepley #if 1
34516ce3c06aSMatthew 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);
34526ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
34536ce3c06aSMatthew 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);
34546ce3c06aSMatthew G. Knepley       }
34556ce3c06aSMatthew G. Knepley #endif
34566ce3c06aSMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
34576ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
34586ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
34599ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
34606ce3c06aSMatthew G. Knepley       orntNew[1] = -3;
34619ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
3462e5337592SStefano Zampini       orntNew[2] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 0)+1) : GetTriMidEdge_Static(ornt[1], 0);
34639ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
34649ddff745SMatthew G. Knepley       orntNew[3] = -3;
34656ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
34666ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
34676ce3c06aSMatthew G. Knepley #if 1
34686ce3c06aSMatthew 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);
34696ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
34706ce3c06aSMatthew 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);
34716ce3c06aSMatthew G. Knepley       }
34726ce3c06aSMatthew G. Knepley #endif
34736ce3c06aSMatthew G. Knepley     }
34746ce3c06aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
34756ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
34766ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4;
3477d3a1cc75SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
34783b61eb6dSMatthew G. Knepley       PetscInt        coneNew[5], orntNew[5], o, of, i;
34796ce3c06aSMatthew G. Knepley 
34806ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
34816ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
3482d3a1cc75SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
3483084f9c62SMatthew G. Knepley       o = ornt[0] < 0 ? -1 : 1;
34846ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
34856ce3c06aSMatthew G. Knepley         coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r);
34866ce3c06aSMatthew G. Knepley         orntNew[0] = ornt[0];
34876ce3c06aSMatthew G. Knepley         coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r);
34886ce3c06aSMatthew G. Knepley         orntNew[1] = ornt[1];
3489084f9c62SMatthew G. Knepley         of = fornt[GetTriEdge_Static(ornt[0], r)]       < 0 ? -1 : 1;
34903b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], r)       + 2;
34913b61eb6dSMatthew 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);
34923b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
34933b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2;
34943b61eb6dSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r);
34953b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
34963b61eb6dSMatthew G. Knepley         of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1;
34973b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2;
34983b61eb6dSMatthew 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);
34993b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
35006ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
35016ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
35026ce3c06aSMatthew G. Knepley #if 1
35036ce3c06aSMatthew 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);
35046ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
35056ce3c06aSMatthew 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);
35066ce3c06aSMatthew G. Knepley         }
35076ce3c06aSMatthew G. Knepley         for (p = 2; p < 5; ++p) {
35086ce3c06aSMatthew 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);
35096ce3c06aSMatthew G. Knepley         }
35106ce3c06aSMatthew G. Knepley #endif
35116ce3c06aSMatthew G. Knepley       }
35126ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3;
35136ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
35146ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3;
35156ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
35163b61eb6dSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1;
35176ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
35183b61eb6dSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2;
35196ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
35203b61eb6dSMatthew G. Knepley       coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0;
35216ce3c06aSMatthew G. Knepley       orntNew[4] = 0;
35226ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
35236ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
35246ce3c06aSMatthew G. Knepley #if 1
35256ce3c06aSMatthew 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);
35266ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
35276ce3c06aSMatthew 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);
35286ce3c06aSMatthew G. Knepley       }
35296ce3c06aSMatthew G. Knepley       for (p = 2; p < 5; ++p) {
35306ce3c06aSMatthew 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);
35316ce3c06aSMatthew G. Knepley       }
35326ce3c06aSMatthew G. Knepley #endif
35336ce3c06aSMatthew G. Knepley     }
35346ce3c06aSMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
35356ce3c06aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
3536854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
35376ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
35386ce3c06aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
35396ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
35406ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
35416ce3c06aSMatthew G. Knepley 
35426ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
35436ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
35446ce3c06aSMatthew G. Knepley       /* A triangle */
35456ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
35466ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
35476ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
35486ce3c06aSMatthew G. Knepley       orntNew[1] = -2;
35496ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
35506ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
35516ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
35526ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
35536ce3c06aSMatthew G. Knepley #if 1
35546ce3c06aSMatthew 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);
35556ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
35566ce3c06aSMatthew 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);
35576ce3c06aSMatthew G. Knepley       }
35586ce3c06aSMatthew G. Knepley #endif
35596ce3c06aSMatthew G. Knepley       /* B triangle */
35606ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
35616ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
35626ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
35636ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
35646ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
35656ce3c06aSMatthew G. Knepley       orntNew[2] = -2;
35666ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
35676ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
35686ce3c06aSMatthew G. Knepley #if 1
35696ce3c06aSMatthew 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);
35706ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
35716ce3c06aSMatthew 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);
35726ce3c06aSMatthew G. Knepley       }
35736ce3c06aSMatthew G. Knepley #endif
35746ce3c06aSMatthew G. Knepley       /* C triangle */
35756ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
35766ce3c06aSMatthew G. Knepley       orntNew[0] = -2;
35776ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
35786ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
35796ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
35806ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
35816ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
35826ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
35836ce3c06aSMatthew G. Knepley #if 1
35846ce3c06aSMatthew 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);
35856ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
35866ce3c06aSMatthew 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);
35876ce3c06aSMatthew G. Knepley       }
35886ce3c06aSMatthew G. Knepley #endif
35896ce3c06aSMatthew G. Knepley       /* D triangle */
35906ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
35916ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
35926ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
35936ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
35946ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
35956ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
35966ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
35976ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
35986ce3c06aSMatthew G. Knepley #if 1
35996ce3c06aSMatthew 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);
36006ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
36016ce3c06aSMatthew 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);
36026ce3c06aSMatthew G. Knepley       }
36036ce3c06aSMatthew G. Knepley #endif
36046ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
36056ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
36066ce3c06aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
36076ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
36089ddff745SMatthew G. Knepley           PetscInt subf;
36096ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
36106ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
36116ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
36126ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
36136ce3c06aSMatthew G. Knepley             if (cone[c] == f) break;
36146ce3c06aSMatthew G. Knepley           }
36159ddff745SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
36166ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
36179ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
36186ce3c06aSMatthew G. Knepley           } else {
36199ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf);
36206ce3c06aSMatthew G. Knepley           }
36216ce3c06aSMatthew G. Knepley         }
36226ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
36236ce3c06aSMatthew G. Knepley #if 1
36249ddff745SMatthew 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);
36256ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
36266ce3c06aSMatthew 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);
36276ce3c06aSMatthew G. Knepley         }
36286ce3c06aSMatthew G. Knepley #endif
36296ce3c06aSMatthew G. Knepley       }
36306ce3c06aSMatthew G. Knepley     }
36316ce3c06aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
36326ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
36336ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8;
36346ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
36356ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
36366ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
36376ce3c06aSMatthew G. Knepley 
36386ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
36396ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
36406ce3c06aSMatthew G. Knepley       /* Face A: {c, a, d} */
3641e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
36426ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
3643e5337592SStefano Zampini       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
36446ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
3645e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2);
36466ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
36476ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
36486ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
36496ce3c06aSMatthew G. Knepley #if 1
36506ce3c06aSMatthew 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);
36516ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
36526ce3c06aSMatthew 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);
36536ce3c06aSMatthew G. Knepley       }
36546ce3c06aSMatthew G. Knepley #endif
36556ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
36566ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
36576ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
36586ce3c06aSMatthew G. Knepley #if 1
36596ce3c06aSMatthew 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);
36606ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
36616ce3c06aSMatthew 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);
36626ce3c06aSMatthew G. Knepley       }
36636ce3c06aSMatthew G. Knepley #endif
36646ce3c06aSMatthew G. Knepley       ++newp;
36656ce3c06aSMatthew G. Knepley       /* Face B: {a, b, e} */
3666e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
36676ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
3668e5337592SStefano Zampini       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0);
36696ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
3670e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
36716ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
36726ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
36736ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
36746ce3c06aSMatthew G. Knepley #if 1
36756ce3c06aSMatthew 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);
36766ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
36776ce3c06aSMatthew 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);
36786ce3c06aSMatthew G. Knepley       }
36796ce3c06aSMatthew G. Knepley #endif
36806ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
36816ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
36826ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
36836ce3c06aSMatthew G. Knepley #if 1
36846ce3c06aSMatthew 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);
36856ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
36866ce3c06aSMatthew 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);
36876ce3c06aSMatthew G. Knepley       }
36886ce3c06aSMatthew G. Knepley #endif
36896ce3c06aSMatthew G. Knepley       ++newp;
36906ce3c06aSMatthew G. Knepley       /* Face C: {c, f, b} */
3691e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
36926ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
3693e5337592SStefano Zampini       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
36946ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
3695e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1);
36966ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
36976ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
36986ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
36996ce3c06aSMatthew G. Knepley #if 1
37006ce3c06aSMatthew 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);
37016ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
37026ce3c06aSMatthew 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);
37036ce3c06aSMatthew G. Knepley       }
37046ce3c06aSMatthew G. Knepley #endif
37056ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
37066ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
37076ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
37086ce3c06aSMatthew G. Knepley #if 1
37096ce3c06aSMatthew 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);
37106ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
37116ce3c06aSMatthew 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);
37126ce3c06aSMatthew G. Knepley       }
37136ce3c06aSMatthew G. Knepley #endif
37146ce3c06aSMatthew G. Knepley       ++newp;
37156ce3c06aSMatthew G. Knepley       /* Face D: {d, e, f} */
3716e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0);
37176ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
3718e5337592SStefano Zampini       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
37196ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
3720e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
37216ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
37226ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37236ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
37246ce3c06aSMatthew G. Knepley #if 1
37256ce3c06aSMatthew 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);
37266ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
37276ce3c06aSMatthew 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);
37286ce3c06aSMatthew G. Knepley       }
37296ce3c06aSMatthew G. Knepley #endif
37306ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
37316ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
37326ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
37336ce3c06aSMatthew G. Knepley #if 1
37346ce3c06aSMatthew 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);
37356ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
37366ce3c06aSMatthew 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);
37376ce3c06aSMatthew G. Knepley       }
37386ce3c06aSMatthew G. Knepley #endif
37396ce3c06aSMatthew G. Knepley       ++newp;
37406ce3c06aSMatthew G. Knepley       /* Face E: {d, f, a} */
3741e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
37426ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
37436ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
37449ddff745SMatthew G. Knepley       orntNew[1] = -2;
3745e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
37466ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
37476ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37486ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
37496ce3c06aSMatthew G. Knepley #if 1
37506ce3c06aSMatthew 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);
37516ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
37526ce3c06aSMatthew 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);
37536ce3c06aSMatthew G. Knepley       }
37546ce3c06aSMatthew G. Knepley #endif
37556ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
37566ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
37576ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
37586ce3c06aSMatthew G. Knepley #if 1
37596ce3c06aSMatthew 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);
37606ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
37616ce3c06aSMatthew 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);
37626ce3c06aSMatthew G. Knepley       }
37636ce3c06aSMatthew G. Knepley #endif
37646ce3c06aSMatthew G. Knepley       ++newp;
37656ce3c06aSMatthew G. Knepley       /* Face F: {c, a, f} */
3766e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
37676ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
37686ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
37699ddff745SMatthew G. Knepley       orntNew[1] = 0;
3770e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
37719ddff745SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
37726ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37736ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
37746ce3c06aSMatthew G. Knepley #if 1
37756ce3c06aSMatthew 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);
37766ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
37776ce3c06aSMatthew 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);
37786ce3c06aSMatthew G. Knepley       }
37796ce3c06aSMatthew G. Knepley #endif
37806ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
37816ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
37826ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
37836ce3c06aSMatthew G. Knepley #if 1
37846ce3c06aSMatthew 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);
37856ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
37866ce3c06aSMatthew 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);
37876ce3c06aSMatthew G. Knepley       }
37886ce3c06aSMatthew G. Knepley #endif
37896ce3c06aSMatthew G. Knepley       ++newp;
37906ce3c06aSMatthew G. Knepley       /* Face G: {e, a, f} */
3791e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
37926ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
37936ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
37949ddff745SMatthew G. Knepley       orntNew[1] = 0;
3795e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
37966ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
37976ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37986ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
37996ce3c06aSMatthew G. Knepley #if 1
38006ce3c06aSMatthew 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);
38016ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
38026ce3c06aSMatthew 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);
38036ce3c06aSMatthew G. Knepley       }
38046ce3c06aSMatthew G. Knepley #endif
38056ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
38066ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
38076ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
38086ce3c06aSMatthew G. Knepley #if 1
38096ce3c06aSMatthew 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);
38106ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
38116ce3c06aSMatthew 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);
38126ce3c06aSMatthew G. Knepley       }
38136ce3c06aSMatthew G. Knepley #endif
38146ce3c06aSMatthew G. Knepley       ++newp;
38156ce3c06aSMatthew G. Knepley       /* Face H: {a, b, f} */
3816e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
38176ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
3818e5337592SStefano Zampini       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
38196ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
38206ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
38219ddff745SMatthew G. Knepley       orntNew[2] = -2;
38226ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
38236ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
38246ce3c06aSMatthew G. Knepley #if 1
38256ce3c06aSMatthew 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);
38266ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
38276ce3c06aSMatthew 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);
38286ce3c06aSMatthew G. Knepley       }
38296ce3c06aSMatthew G. Knepley #endif
38306ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
38316ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
38326ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
38336ce3c06aSMatthew G. Knepley #if 1
38346ce3c06aSMatthew 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);
38356ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
38366ce3c06aSMatthew 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);
38376ce3c06aSMatthew G. Knepley       }
38386ce3c06aSMatthew G. Knepley #endif
38396ce3c06aSMatthew G. Knepley       ++newp;
38406ce3c06aSMatthew G. Knepley     }
38416ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
38426ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
38436ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
38446ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
38456ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
38466ce3c06aSMatthew G. Knepley 
38476ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
38486ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
38496ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
38506ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
38516ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
38526ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
38536ce3c06aSMatthew G. Knepley 
38546ce3c06aSMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
38556ce3c06aSMatthew G. Knepley         orntNew[0]   = ornt[0];
38566ce3c06aSMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
38576ce3c06aSMatthew G. Knepley         orntNew[1]   = ornt[1];
38586ce3c06aSMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax);
38596ce3c06aSMatthew G. Knepley         orntNew[2+r] = 0;
38606ce3c06aSMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd      - eMax) + (f - fMax);
38616ce3c06aSMatthew G. Knepley         orntNew[3-r] = 0;
38626ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
38636ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
38646ce3c06aSMatthew G. Knepley #if 1
38656ce3c06aSMatthew 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);
38666ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
38676ce3c06aSMatthew 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);
38686ce3c06aSMatthew G. Knepley         }
38696ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
38706ce3c06aSMatthew 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);
38716ce3c06aSMatthew G. Knepley         }
38726ce3c06aSMatthew G. Knepley #endif
38736ce3c06aSMatthew G. Knepley         for (s = 0; s < size; ++s) {
3874d3a1cc75SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
3875084f9c62SMatthew G. Knepley           PetscInt        o, of;
38766ce3c06aSMatthew G. Knepley 
38776ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
38786ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
3879084f9c62SMatthew G. Knepley           o = orntCell[0] < 0 ? -1 : 1;
38806ce3c06aSMatthew G. Knepley           for (c = 2; c < 5; ++c) if (coneCell[c] == f) break;
38816ce3c06aSMatthew 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]);
3882d3a1cc75SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
3883084f9c62SMatthew G. Knepley           of = fornt[c-2] < 0 ? -1 : 1;
3884084f9c62SMatthew 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;
38856ce3c06aSMatthew G. Knepley         }
38866ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
38876ce3c06aSMatthew G. Knepley #if 1
38886ce3c06aSMatthew 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);
38896ce3c06aSMatthew G. Knepley         for (p = 0; p < size; ++p) {
38906ce3c06aSMatthew 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);
38916ce3c06aSMatthew G. Knepley         }
38926ce3c06aSMatthew G. Knepley #endif
38936ce3c06aSMatthew G. Knepley       }
38946ce3c06aSMatthew G. Knepley     }
38956ce3c06aSMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
38966ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
38976ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3;
38986ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
38996ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
39006ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
39016ce3c06aSMatthew G. Knepley 
39026ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
39036ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
39046ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
3905b598a9d5SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3;
39066ce3c06aSMatthew G. Knepley         orntNew[0] = 0;
3907b598a9d5SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3;
39086ce3c06aSMatthew G. Knepley         orntNew[1] = 0;
3909b598a9d5SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax);
39106ce3c06aSMatthew G. Knepley         orntNew[2] = 0;
3911b598a9d5SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r]       - fMax);
39126ce3c06aSMatthew G. Knepley         orntNew[3] = 0;
39136ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
39146ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
39156ce3c06aSMatthew G. Knepley #if 1
39166ce3c06aSMatthew 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);
39176ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
39186ce3c06aSMatthew 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);
39196ce3c06aSMatthew G. Knepley         }
39206ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
39216ce3c06aSMatthew 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);
39226ce3c06aSMatthew G. Knepley         }
39236ce3c06aSMatthew G. Knepley #endif
39246ce3c06aSMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r);
39256ce3c06aSMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3;
39266ce3c06aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
39276ce3c06aSMatthew G. Knepley #if 1
39286ce3c06aSMatthew 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);
39296ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
39306ce3c06aSMatthew 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);
39316ce3c06aSMatthew G. Knepley         }
39326ce3c06aSMatthew G. Knepley #endif
39336ce3c06aSMatthew G. Knepley       }
39346ce3c06aSMatthew G. Knepley     }
39356ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
39366ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
39376ce3c06aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
39386ce3c06aSMatthew G. Knepley 
39396ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
39406ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
39416ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
39426ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
39436ce3c06aSMatthew G. Knepley 
39446ce3c06aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
39456ce3c06aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
39466ce3c06aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
39476ce3c06aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
39486ce3c06aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
39496ce3c06aSMatthew G. Knepley #if 1
39506ce3c06aSMatthew 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);
39516ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
39526ce3c06aSMatthew 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);
39536ce3c06aSMatthew G. Knepley         }
39546ce3c06aSMatthew G. Knepley #endif
39556ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
39566ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
39576ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
39586ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
39596ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
39606ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
39616ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == e) break;
39626ce3c06aSMatthew G. Knepley           if (support[s] < fMax) {
39636ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
39646ce3c06aSMatthew G. Knepley           } else {
39656ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
39666ce3c06aSMatthew G. Knepley           }
39676ce3c06aSMatthew G. Knepley         }
39686ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
39696ce3c06aSMatthew G. Knepley #if 1
39706ce3c06aSMatthew 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);
39716ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
39726ce3c06aSMatthew 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);
39736ce3c06aSMatthew G. Knepley         }
39746ce3c06aSMatthew G. Knepley #endif
39756ce3c06aSMatthew G. Knepley       }
39766ce3c06aSMatthew G. Knepley     }
39776ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
39786ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
39796ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
39806ce3c06aSMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
39816ce3c06aSMatthew G. Knepley 
39826ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
39836ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
39846ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
39856ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
39866ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
39876ce3c06aSMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
39886ce3c06aSMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
39896ce3c06aSMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
39906ce3c06aSMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
39916ce3c06aSMatthew G. Knepley 
39926ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
39936ce3c06aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
39946ce3c06aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
39956ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
39966ce3c06aSMatthew G. Knepley #if 1
39976ce3c06aSMatthew 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);
39986ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
39996ce3c06aSMatthew 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);
40006ce3c06aSMatthew G. Knepley         }
40016ce3c06aSMatthew G. Knepley #endif
40026ce3c06aSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
40036ce3c06aSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
40046ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
40056ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
40066ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
40076ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
40086ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
40096ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
40106ce3c06aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
4011e5337592SStefano Zampini             er = GetTriMidEdgeInverse_Static(ornt[c], r);
40126ce3c06aSMatthew G. Knepley             if (er == eint[c]) {
40136ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
40146ce3c06aSMatthew G. Knepley             } else {
40156ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
40166ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
40176ce3c06aSMatthew G. Knepley             }
40186ce3c06aSMatthew G. Knepley           } else {
4019b598a9d5SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3;
40206ce3c06aSMatthew G. Knepley           }
40216ce3c06aSMatthew G. Knepley         }
40226ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
40236ce3c06aSMatthew G. Knepley #if 1
40246ce3c06aSMatthew 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);
40256ce3c06aSMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
40266ce3c06aSMatthew 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);
40276ce3c06aSMatthew G. Knepley         }
40286ce3c06aSMatthew G. Knepley #endif
40296ce3c06aSMatthew G. Knepley       }
40306ce3c06aSMatthew G. Knepley     }
40316ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
40326ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
40336ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
40346ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
40356ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
40366ce3c06aSMatthew G. Knepley 
40376ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
40386ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
40396ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
40406ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
40416ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
40426ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
40436ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
40446ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
40456ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
40466ce3c06aSMatthew G. Knepley #if 1
40476ce3c06aSMatthew 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);
40486ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
40496ce3c06aSMatthew 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);
40506ce3c06aSMatthew G. Knepley       }
40516ce3c06aSMatthew G. Knepley #endif
40526ce3c06aSMatthew G. Knepley       supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
40536ce3c06aSMatthew G. Knepley       supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
40546ce3c06aSMatthew G. Knepley       supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
40556ce3c06aSMatthew G. Knepley       supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
40566ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
40576ce3c06aSMatthew G. Knepley #if 1
40586ce3c06aSMatthew 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);
40596ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
40606ce3c06aSMatthew 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);
40616ce3c06aSMatthew G. Knepley       }
40626ce3c06aSMatthew G. Knepley #endif
40636ce3c06aSMatthew G. Knepley     }
40646ce3c06aSMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
40656ce3c06aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
40666ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
40676ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
40686ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
40696ce3c06aSMatthew G. Knepley 
40706ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
40716ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
40726ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
40736ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
40746ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
40756ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
40766ce3c06aSMatthew G. Knepley #if 1
40776ce3c06aSMatthew 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);
40786ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
40796ce3c06aSMatthew 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);
40806ce3c06aSMatthew G. Knepley       }
40816ce3c06aSMatthew G. Knepley #endif
40826ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
40836ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
40846ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
40856ce3c06aSMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
40866ce3c06aSMatthew 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]);
40876ce3c06aSMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2;
40886ce3c06aSMatthew G. Knepley       }
40896ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
40906ce3c06aSMatthew G. Knepley #if 1
40916ce3c06aSMatthew 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);
40926ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
40936ce3c06aSMatthew 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);
40946ce3c06aSMatthew G. Knepley       }
40956ce3c06aSMatthew G. Knepley #endif
40966ce3c06aSMatthew G. Knepley     }
40976ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
40986ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
40996ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
4100623f4348SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
41016ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
41026ce3c06aSMatthew G. Knepley 
41036ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
41046ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
41056ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
41066ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
41076ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
41086ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
41096ce3c06aSMatthew G. Knepley #if 1
41106ce3c06aSMatthew 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);
41116ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
41126ce3c06aSMatthew 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);
41136ce3c06aSMatthew G. Knepley       }
41146ce3c06aSMatthew G. Knepley #endif
41156ce3c06aSMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0;
41166ce3c06aSMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1;
41176ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
41186ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
41196ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
4120623f4348SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
41216ce3c06aSMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
41226ce3c06aSMatthew 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]);
4123b598a9d5SMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2;
4124b598a9d5SMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3;
41256ce3c06aSMatthew G. Knepley       }
41266ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
41276ce3c06aSMatthew G. Knepley #if 1
41286ce3c06aSMatthew 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);
41296ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
41306ce3c06aSMatthew 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);
41316ce3c06aSMatthew G. Knepley       }
41326ce3c06aSMatthew G. Knepley #endif
41336ce3c06aSMatthew G. Knepley     }
41346ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
41356ce3c06aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
41366ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
41376ce3c06aSMatthew G. Knepley       const PetscInt *support, *cone;
41386ce3c06aSMatthew G. Knepley       PetscInt        size, s;
41396ce3c06aSMatthew G. Knepley 
41406ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
41416ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
41426ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
41436ce3c06aSMatthew G. Knepley         PetscInt r = 0;
41446ce3c06aSMatthew G. Knepley 
41456ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
41466ce3c06aSMatthew G. Knepley         if (cone[1] == v) r = 1;
41476ce3c06aSMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
41486ce3c06aSMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax);
41496ce3c06aSMatthew G. Knepley       }
41506ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
41516ce3c06aSMatthew G. Knepley #if 1
41526ce3c06aSMatthew 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);
41536ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
41546ce3c06aSMatthew 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);
41556ce3c06aSMatthew G. Knepley       }
41566ce3c06aSMatthew G. Knepley #endif
41576ce3c06aSMatthew G. Knepley     }
41586ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
41596ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
41606ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
41616ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support;
41626ce3c06aSMatthew G. Knepley       PetscInt       *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s;
41636ce3c06aSMatthew G. Knepley 
41646ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
41656ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
41666ce3c06aSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
41676ce3c06aSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
41686ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
41696ce3c06aSMatthew G. Knepley         PetscInt r = 0;
41706ce3c06aSMatthew G. Knepley 
41716ce3c06aSMatthew G. Knepley         if (support[s] < fMax) {
41726ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
41736ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
41746ce3c06aSMatthew G. Knepley           for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
41756ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
41766ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
41776ce3c06aSMatthew G. Knepley           faceSize += 2;
41786ce3c06aSMatthew G. Knepley         } else {
41796ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax);
41806ce3c06aSMatthew G. Knepley           ++faceSize;
41816ce3c06aSMatthew G. Knepley         }
41826ce3c06aSMatthew G. Knepley       }
41836ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
41846ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
41856ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
41866ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
41876ce3c06aSMatthew G. Knepley 
41886ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
41896ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
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[0], &cone);CHKERRQ(ierr);
41936ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
41946ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
41956ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
41966ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
41976ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
41986ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
41996ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);}
42006ce3c06aSMatthew G. Knepley         }
42016ce3c06aSMatthew G. Knepley       }
42026ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
42036ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
42046ce3c06aSMatthew G. Knepley #if 1
42056ce3c06aSMatthew 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);
42066ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+faceSize+cellSize; ++p) {
42076ce3c06aSMatthew 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);
42086ce3c06aSMatthew G. Knepley       }
42096ce3c06aSMatthew G. Knepley #endif
42106ce3c06aSMatthew G. Knepley     }
42116ce3c06aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
42126ce3c06aSMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
42136ce3c06aSMatthew G. Knepley     break;
4214e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_3D:
4215e5337592SStefano Zampini     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
4216e5337592SStefano Zampini     /* All cells have 6 faces */
4217e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
4218e5337592SStefano Zampini       const PetscInt  newp = cStartNew + (c - cStart)*4;
4219e5337592SStefano Zampini       const PetscInt *cone, *ornt;
4220e5337592SStefano Zampini       PetscInt        coneNew[6];
4221e5337592SStefano Zampini       PetscInt        orntNew[6];
4222e5337592SStefano Zampini 
4223e5337592SStefano Zampini       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
4224e5337592SStefano Zampini       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
4225e5337592SStefano Zampini       /* A hex */
4226e5337592SStefano Zampini       coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */
4227e5337592SStefano Zampini       orntNew[0] = ornt[0] < 0 ? -1 : 1;
4228e5337592SStefano Zampini       coneNew[1] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 3;               /* T */
4229e5337592SStefano Zampini       orntNew[1] = -4;
4230e5337592SStefano Zampini       coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */
4231e5337592SStefano Zampini       orntNew[2] = ornt[2] < 0 ? -1 : 1;
4232e5337592SStefano Zampini       coneNew[3] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 0;               /* K */
4233e5337592SStefano Zampini       orntNew[3] = -1;
4234e5337592SStefano Zampini       coneNew[4] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 2;               /* R */
4235e5337592SStefano Zampini       orntNew[4] = 0;
4236e5337592SStefano Zampini       coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */
4237e5337592SStefano Zampini       orntNew[5] = ornt[1] < 0 ? -1 : 1;
4238e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
4239e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
4240e5337592SStefano Zampini #if 1
4241e5337592SStefano 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);
4242e5337592SStefano Zampini       for (p = 0; p < 6; ++p) {
4243e5337592SStefano 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);
4244e5337592SStefano Zampini       }
4245e5337592SStefano Zampini #endif
4246e5337592SStefano Zampini       /* B hex */
4247e5337592SStefano Zampini       coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */
4248e5337592SStefano Zampini       orntNew[0] = ornt[0] < 0 ? -2 : 0;
4249e5337592SStefano Zampini       coneNew[1] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 4;               /* T */
4250e5337592SStefano Zampini       orntNew[1] = 0;
4251e5337592SStefano Zampini       coneNew[2] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 0;               /* F */
4252e5337592SStefano Zampini       orntNew[2] = 0;
4253e5337592SStefano Zampini       coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */
4254e5337592SStefano Zampini       orntNew[3] = ornt[3] < 0 ? -2 : 0;
4255e5337592SStefano Zampini       coneNew[4] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 1;               /* R */
4256e5337592SStefano Zampini       orntNew[4] = 0;
4257e5337592SStefano Zampini       coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */
4258e5337592SStefano Zampini       orntNew[5] = ornt[1] < 0 ? -4 : 2;
4259e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
4260e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
4261e5337592SStefano Zampini #if 1
4262e5337592SStefano 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);
4263e5337592SStefano Zampini       for (p = 0; p < 6; ++p) {
4264e5337592SStefano 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);
4265e5337592SStefano Zampini       }
4266e5337592SStefano Zampini #endif
4267e5337592SStefano Zampini       /* C hex */
4268e5337592SStefano Zampini       coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */
4269e5337592SStefano Zampini       orntNew[0] = ornt[0] < 0 ? -4 : 2;
4270e5337592SStefano Zampini       coneNew[1] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 5;               /* T */
4271e5337592SStefano Zampini       orntNew[1] = -4;
4272e5337592SStefano Zampini       coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */
4273e5337592SStefano Zampini       orntNew[2] = ornt[2] < 0 ? -2 : 0;
4274e5337592SStefano Zampini       coneNew[3] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 1;               /* K */
4275e5337592SStefano Zampini       orntNew[3] = -1;
4276e5337592SStefano Zampini       coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */
4277e5337592SStefano Zampini       orntNew[4] = ornt[3] < 0 ? -1 : 1;
4278e5337592SStefano Zampini       coneNew[5] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 2;               /* L */
4279e5337592SStefano Zampini       orntNew[5] = -4;
4280e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
4281e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
4282e5337592SStefano Zampini #if 1
4283e5337592SStefano 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);
4284e5337592SStefano Zampini       for (p = 0; p < 6; ++p) {
4285e5337592SStefano 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);
4286e5337592SStefano Zampini       }
4287e5337592SStefano Zampini #endif
4288e5337592SStefano Zampini       /* D hex */
4289e5337592SStefano Zampini       coneNew[0] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 3;               /* B */
4290e5337592SStefano Zampini       orntNew[0] = 0;
4291e5337592SStefano Zampini       coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */
4292e5337592SStefano Zampini       orntNew[1] = ornt[3] < 0 ? -1 : 1;
4293e5337592SStefano Zampini       coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */
4294e5337592SStefano Zampini       orntNew[2] = ornt[2] < 0 ? -4 : 2;
4295e5337592SStefano Zampini       coneNew[3] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 4;               /* K */
4296e5337592SStefano Zampini       orntNew[3] = -1;
4297e5337592SStefano Zampini       coneNew[4] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 5;               /* R */
4298e5337592SStefano Zampini       orntNew[4] = 0;
4299e5337592SStefano Zampini       coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */
4300e5337592SStefano Zampini       orntNew[5] = ornt[1] < 0 ? -2 : 0;
4301e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
4302e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
4303e5337592SStefano Zampini #if 1
4304e5337592SStefano 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);
4305e5337592SStefano Zampini       for (p = 0; p < 6; ++p) {
4306e5337592SStefano 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);
4307e5337592SStefano Zampini       }
4308e5337592SStefano Zampini #endif
4309e5337592SStefano Zampini     }
4310e5337592SStefano Zampini     /* Split faces have 4 edges and the same cells as the parent */
4311e5337592SStefano Zampini     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
4312e5337592SStefano Zampini     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
4313e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
4314e5337592SStefano Zampini       const PetscInt  newp = fStartNew + (f - fStart)*3;
4315e5337592SStefano Zampini       const PetscInt *cone, *ornt, *support;
4316e5337592SStefano Zampini       PetscInt        coneNew[4], orntNew[4], coneSize, supportSize, s;
4317e5337592SStefano Zampini 
4318e5337592SStefano Zampini       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
4319e5337592SStefano Zampini       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
4320e5337592SStefano Zampini       /* A quad */
4321e5337592SStefano Zampini       coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
4322e5337592SStefano Zampini       orntNew[0] = ornt[2];
4323e5337592SStefano Zampini       coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
4324e5337592SStefano Zampini       orntNew[1] = ornt[0];
4325e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
4326e5337592SStefano Zampini       orntNew[2] = 0;
4327e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
4328e5337592SStefano Zampini       orntNew[3] = -2;
4329e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
4330e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
4331e5337592SStefano Zampini #if 1
4332e5337592SStefano 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);
4333e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4334e5337592SStefano 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);
4335e5337592SStefano Zampini       }
4336e5337592SStefano Zampini #endif
4337e5337592SStefano Zampini       /* B quad */
4338e5337592SStefano Zampini       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
4339e5337592SStefano Zampini       orntNew[0] = ornt[0];
4340e5337592SStefano Zampini       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
4341e5337592SStefano Zampini       orntNew[1] = ornt[1];
4342e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
4343e5337592SStefano Zampini       orntNew[2] = 0;
4344e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
4345e5337592SStefano Zampini       orntNew[3] = -2;
4346e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
4347e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
4348e5337592SStefano Zampini #if 1
4349e5337592SStefano 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);
4350e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4351e5337592SStefano 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);
4352e5337592SStefano Zampini       }
4353e5337592SStefano Zampini #endif
4354e5337592SStefano Zampini       /* C quad */
4355e5337592SStefano Zampini       coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
4356e5337592SStefano Zampini       orntNew[0] = ornt[1];
4357e5337592SStefano Zampini       coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
4358e5337592SStefano Zampini       orntNew[1] = ornt[2];
4359e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
4360e5337592SStefano Zampini       orntNew[2] = 0;
4361e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
4362e5337592SStefano Zampini       orntNew[3] = -2;
4363e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
4364e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
4365e5337592SStefano Zampini #if 1
4366e5337592SStefano 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);
4367e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4368e5337592SStefano 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);
4369e5337592SStefano Zampini       }
4370e5337592SStefano Zampini #endif
4371e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
4372e5337592SStefano Zampini       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
4373e5337592SStefano Zampini       for (r = 0; r < 3; ++r) {
4374e5337592SStefano Zampini         for (s = 0; s < supportSize; ++s) {
4375e5337592SStefano Zampini           PetscInt subf;
4376e5337592SStefano Zampini           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
4377e5337592SStefano Zampini           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4378e5337592SStefano Zampini           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
4379e5337592SStefano Zampini           for (c = 0; c < coneSize; ++c) {
4380e5337592SStefano Zampini             if (cone[c] == f) break;
4381e5337592SStefano Zampini           }
4382e5337592SStefano Zampini           subf = GetTriSubfaceInverse_Static(ornt[c], r);
4383e5337592SStefano Zampini           supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf];
4384e5337592SStefano Zampini         }
4385e5337592SStefano Zampini         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
4386e5337592SStefano Zampini #if 1
4387e5337592SStefano 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);
4388e5337592SStefano Zampini         for (p = 0; p < supportSize; ++p) {
4389e5337592SStefano 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);
4390e5337592SStefano Zampini         }
4391e5337592SStefano Zampini #endif
4392e5337592SStefano Zampini       }
4393e5337592SStefano Zampini     }
4394e5337592SStefano Zampini     /* Interior faces have 4 edges and 2 cells */
4395e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
4396e5337592SStefano Zampini       PetscInt        newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6;
4397e5337592SStefano Zampini       const PetscInt *cone, *ornt;
4398e5337592SStefano Zampini       PetscInt        coneNew[4], orntNew[4];
4399e5337592SStefano Zampini       PetscInt        supportNew[2];
4400e5337592SStefano Zampini 
4401e5337592SStefano Zampini       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
4402e5337592SStefano Zampini       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
4403e5337592SStefano Zampini       /* Face {a, g, m, h} */
4404e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0);
4405e5337592SStefano Zampini       orntNew[0] = 0;
4406e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
4407e5337592SStefano Zampini       orntNew[1] = 0;
4408e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
4409e5337592SStefano Zampini       orntNew[2] = -2;
4410e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2);
4411e5337592SStefano Zampini       orntNew[3] = -2;
4412e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4413e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4414e5337592SStefano Zampini #if 1
4415e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4416e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4417e5337592SStefano 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);
4418e5337592SStefano Zampini       }
4419e5337592SStefano Zampini #endif
4420e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 0;
4421e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 1;
4422e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4423e5337592SStefano Zampini #if 1
4424e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4425e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4426e5337592SStefano 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);
4427e5337592SStefano Zampini       }
4428e5337592SStefano Zampini #endif
4429e5337592SStefano Zampini       ++newp;
4430e5337592SStefano Zampini       /* Face {g, b, l , m} */
4431e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1);
4432e5337592SStefano Zampini       orntNew[0] = -2;
4433e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0);
4434e5337592SStefano Zampini       orntNew[1] = 0;
4435e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
4436e5337592SStefano Zampini       orntNew[2] = 0;
4437e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
4438e5337592SStefano Zampini       orntNew[3] = -2;
4439e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4440e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4441e5337592SStefano Zampini #if 1
4442e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4443e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4444e5337592SStefano 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);
4445e5337592SStefano Zampini       }
4446e5337592SStefano Zampini #endif
4447e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 1;
4448e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 2;
4449e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4450e5337592SStefano Zampini #if 1
4451e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4452e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4453e5337592SStefano 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);
4454e5337592SStefano Zampini       }
4455e5337592SStefano Zampini #endif
4456e5337592SStefano Zampini       ++newp;
4457e5337592SStefano Zampini       /* Face {c, g, m, i} */
4458e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2);
4459e5337592SStefano Zampini       orntNew[0] = 0;
4460e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
4461e5337592SStefano Zampini       orntNew[1] = 0;
4462e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
4463e5337592SStefano Zampini       orntNew[2] = -2;
4464e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0);
4465e5337592SStefano Zampini       orntNew[3] = -2;
4466e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4467e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4468e5337592SStefano Zampini #if 1
4469e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4470e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4471e5337592SStefano 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);
4472e5337592SStefano Zampini       }
4473e5337592SStefano Zampini #endif
4474e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 0;
4475e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 2;
4476e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4477e5337592SStefano Zampini #if 1
4478e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4479e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4480e5337592SStefano 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);
4481e5337592SStefano Zampini       }
4482e5337592SStefano Zampini #endif
4483e5337592SStefano Zampini       ++newp;
4484e5337592SStefano Zampini       /* Face {d, h, m, i} */
4485e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0);
4486e5337592SStefano Zampini       orntNew[0] = 0;
4487e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
4488e5337592SStefano Zampini       orntNew[1] = 0;
4489e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
4490e5337592SStefano Zampini       orntNew[2] = -2;
4491e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2);
4492e5337592SStefano Zampini       orntNew[3] = -2;
4493e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4494e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4495e5337592SStefano Zampini #if 1
4496e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4497e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4498e5337592SStefano 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);
4499e5337592SStefano Zampini       }
4500e5337592SStefano Zampini #endif
4501e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 0;
4502e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 3;
4503e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4504e5337592SStefano Zampini #if 1
4505e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4506e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4507e5337592SStefano 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);
4508e5337592SStefano Zampini       }
4509e5337592SStefano Zampini #endif
4510e5337592SStefano Zampini       ++newp;
4511e5337592SStefano Zampini       /* Face {h, m, l, e} */
4512e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
4513e5337592SStefano Zampini       orntNew[0] = 0;
4514e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
4515e5337592SStefano Zampini       orntNew[1] = -2;
4516e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1);
4517e5337592SStefano Zampini       orntNew[2] = -2;
4518e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1);
4519e5337592SStefano Zampini       orntNew[3] = 0;
4520e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4521e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4522e5337592SStefano Zampini #if 1
4523e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4524e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4525e5337592SStefano 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);
4526e5337592SStefano Zampini       }
4527e5337592SStefano Zampini #endif
4528e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 1;
4529e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 3;
4530e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4531e5337592SStefano Zampini #if 1
4532e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4533e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4534e5337592SStefano 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);
4535e5337592SStefano Zampini       }
4536e5337592SStefano Zampini #endif
4537e5337592SStefano Zampini       ++newp;
4538e5337592SStefano Zampini       /* Face {i, m, l, f} */
4539e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
4540e5337592SStefano Zampini       orntNew[0] = 0;
4541e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
4542e5337592SStefano Zampini       orntNew[1] = -2;
4543e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2);
4544e5337592SStefano Zampini       orntNew[2] = -2;
4545e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1);
4546e5337592SStefano Zampini       orntNew[3] = 0;
4547e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4548e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4549e5337592SStefano Zampini #if 1
4550e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4551e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4552e5337592SStefano 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);
4553e5337592SStefano Zampini       }
4554e5337592SStefano Zampini #endif
4555e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 2;
4556e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 3;
4557e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4558e5337592SStefano Zampini #if 1
4559e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4560e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4561e5337592SStefano 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);
4562e5337592SStefano Zampini       }
4563e5337592SStefano Zampini #endif
4564e5337592SStefano Zampini       ++newp;
4565e5337592SStefano Zampini     }
4566e5337592SStefano Zampini     /* Split Edges have 2 vertices and the same faces as the parent */
4567e5337592SStefano Zampini     for (e = eStart; e < eEnd; ++e) {
4568e5337592SStefano Zampini       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
4569e5337592SStefano Zampini 
4570e5337592SStefano Zampini       for (r = 0; r < 2; ++r) {
4571e5337592SStefano Zampini         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
4572e5337592SStefano Zampini         const PetscInt *cone, *ornt, *support;
4573e5337592SStefano Zampini         PetscInt        coneNew[2], coneSize, c, supportSize, s;
4574e5337592SStefano Zampini 
4575e5337592SStefano Zampini         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
4576e5337592SStefano Zampini         coneNew[0]       = vStartNew + (cone[0] - vStart);
4577e5337592SStefano Zampini         coneNew[1]       = vStartNew + (cone[1] - vStart);
4578e5337592SStefano Zampini         coneNew[(r+1)%2] = newv;
4579e5337592SStefano Zampini         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4580e5337592SStefano Zampini #if 1
4581e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4582e5337592SStefano Zampini         for (p = 0; p < 2; ++p) {
4583e5337592SStefano 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);
4584e5337592SStefano Zampini         }
4585e5337592SStefano Zampini #endif
4586e5337592SStefano Zampini         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
4587e5337592SStefano Zampini         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
4588e5337592SStefano Zampini         for (s = 0; s < supportSize; ++s) {
4589e5337592SStefano Zampini           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
4590e5337592SStefano Zampini           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4591e5337592SStefano Zampini           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
4592e5337592SStefano Zampini           for (c = 0; c < coneSize; ++c) {
4593e5337592SStefano Zampini             if (cone[c] == e) break;
4594e5337592SStefano Zampini           }
4595e5337592SStefano Zampini           supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3;
4596e5337592SStefano Zampini         }
4597e5337592SStefano Zampini         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4598e5337592SStefano Zampini #if 1
4599e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4600e5337592SStefano Zampini         for (p = 0; p < supportSize; ++p) {
4601e5337592SStefano 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);
4602e5337592SStefano Zampini         }
4603e5337592SStefano Zampini #endif
4604e5337592SStefano Zampini       }
4605e5337592SStefano Zampini     }
4606e5337592SStefano Zampini     /* Face edges have 2 vertices and 2 + cell faces supports */
4607e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
4608e5337592SStefano Zampini       const PetscInt *cone, *ornt, *support;
4609e5337592SStefano Zampini       PetscInt        coneSize, supportSize, s;
4610e5337592SStefano Zampini 
4611e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
4612e5337592SStefano Zampini       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
4613e5337592SStefano Zampini       for (r = 0; r < 3; ++r) {
4614e5337592SStefano Zampini         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
4615e5337592SStefano Zampini         PetscInt        coneNew[2];
4616e5337592SStefano Zampini         PetscInt        fint[4][3] = { {0, 1, 2},
4617e5337592SStefano Zampini                                        {3, 4, 0},
4618e5337592SStefano Zampini                                        {2, 5, 3},
4619e5337592SStefano Zampini                                        {1, 4, 5} };
4620e5337592SStefano Zampini 
4621e5337592SStefano Zampini         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
4622e5337592SStefano Zampini         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
4623e5337592SStefano Zampini         coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart;
4624e5337592SStefano Zampini         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4625e5337592SStefano Zampini #if 1
4626e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4627e5337592SStefano Zampini         for (p = 0; p < 2; ++p) {
4628e5337592SStefano 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);
4629e5337592SStefano Zampini         }
4630e5337592SStefano Zampini #endif
4631e5337592SStefano Zampini         supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3;
4632e5337592SStefano Zampini         supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3;
4633e5337592SStefano Zampini         for (s = 0; s < supportSize; ++s) {
4634e5337592SStefano Zampini           PetscInt er;
4635e5337592SStefano Zampini           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
4636e5337592SStefano Zampini           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4637e5337592SStefano Zampini           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
4638e5337592SStefano Zampini           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
4639e5337592SStefano Zampini           er = GetTriInteriorEdgeInverse_Static(ornt[c], r);
4640e5337592SStefano Zampini           supportRef[2+s] = fStartNew + (fEnd - fStart)*3 + (support[s] - cStart)*6 + fint[c][er];
4641e5337592SStefano Zampini         }
4642e5337592SStefano Zampini         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4643e5337592SStefano Zampini #if 1
4644e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4645e5337592SStefano Zampini         for (p = 0; p < supportSize + 2; ++p) {
4646e5337592SStefano 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);
4647e5337592SStefano Zampini         }
4648e5337592SStefano Zampini #endif
4649e5337592SStefano Zampini       }
4650e5337592SStefano Zampini     }
4651e5337592SStefano Zampini     /* Interior cell edges have 2 vertices and 3 faces */
4652e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
4653e5337592SStefano Zampini       const PetscInt *cone;
4654e5337592SStefano Zampini       PetscInt       fint[4][3] = { {0,1,2},
4655e5337592SStefano Zampini                                     {0,3,4},
4656e5337592SStefano Zampini                                     {2,3,5},
4657e5337592SStefano Zampini                                     {1,4,5} } ;
4658e5337592SStefano Zampini 
4659e5337592SStefano Zampini       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
4660e5337592SStefano Zampini       for (r = 0; r < 4; r++) {
4661e5337592SStefano Zampini         PetscInt       coneNew[2], supportNew[3];
4662e5337592SStefano Zampini         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r;
4663e5337592SStefano Zampini 
4664e5337592SStefano Zampini         coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
4665e5337592SStefano Zampini         coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd -fStart) + c - cStart;
4666e5337592SStefano Zampini         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4667e5337592SStefano Zampini #if 1
4668e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4669e5337592SStefano Zampini         for (p = 0; p < 2; ++p) {
4670e5337592SStefano 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);
4671e5337592SStefano Zampini         }
4672e5337592SStefano Zampini #endif
4673e5337592SStefano Zampini         supportNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][0];
4674e5337592SStefano Zampini         supportNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][1];
4675e5337592SStefano Zampini         supportNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][2];
4676e5337592SStefano Zampini         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4677e5337592SStefano Zampini #if 1
4678e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4679e5337592SStefano Zampini         for (p = 0; p < 3; ++p) {
4680e5337592SStefano 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);
4681e5337592SStefano Zampini         }
4682e5337592SStefano Zampini #endif
4683e5337592SStefano Zampini       }
4684e5337592SStefano Zampini     }
4685e5337592SStefano Zampini     /* Old vertices have identical supports */
4686e5337592SStefano Zampini     for (v = vStart; v < vEnd; ++v) {
4687e5337592SStefano Zampini       const PetscInt  newp = vStartNew + (v - vStart);
4688e5337592SStefano Zampini       const PetscInt *support, *cone;
4689e5337592SStefano Zampini       PetscInt        size, s;
4690e5337592SStefano Zampini 
4691e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
4692e5337592SStefano Zampini       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
4693e5337592SStefano Zampini       for (s = 0; s < size; ++s) {
4694e5337592SStefano Zampini         PetscInt r = 0;
4695e5337592SStefano Zampini 
4696e5337592SStefano Zampini         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4697e5337592SStefano Zampini         if (cone[1] == v) r = 1;
4698e5337592SStefano Zampini         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
4699e5337592SStefano Zampini       }
4700e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4701e5337592SStefano Zampini #if 1
4702e5337592SStefano Zampini       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
4703e5337592SStefano Zampini       for (p = 0; p < size; ++p) {
4704e5337592SStefano 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);
4705e5337592SStefano Zampini       }
4706e5337592SStefano Zampini #endif
4707e5337592SStefano Zampini     }
4708e5337592SStefano Zampini     /* Edge vertices have 2 + faces supports */
4709e5337592SStefano Zampini     for (e = eStart; e < eEnd; ++e) {
4710e5337592SStefano Zampini       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
4711e5337592SStefano Zampini       const PetscInt *cone, *support;
4712e5337592SStefano Zampini       PetscInt        size, s;
4713e5337592SStefano Zampini 
4714e5337592SStefano Zampini       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
4715e5337592SStefano Zampini       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
4716e5337592SStefano Zampini       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
4717e5337592SStefano Zampini       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
4718e5337592SStefano Zampini       for (s = 0; s < size; ++s) {
4719e5337592SStefano Zampini         PetscInt r = 0, coneSize;
4720e5337592SStefano Zampini 
4721e5337592SStefano Zampini         ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
4722e5337592SStefano Zampini         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4723e5337592SStefano Zampini         for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
4724e5337592SStefano Zampini         supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + r;
4725e5337592SStefano Zampini       }
4726e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4727e5337592SStefano Zampini #if 1
4728e5337592SStefano Zampini       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
4729e5337592SStefano Zampini       for (p = 0; p < 2+size; ++p) {
4730e5337592SStefano 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);
4731e5337592SStefano Zampini       }
4732e5337592SStefano Zampini #endif
4733e5337592SStefano Zampini     }
4734e5337592SStefano Zampini     /* Face vertices have 3 + cells supports */
4735e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
4736e5337592SStefano Zampini       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
4737e5337592SStefano Zampini       const PetscInt *cone, *support;
4738e5337592SStefano Zampini       PetscInt        size, s;
4739e5337592SStefano Zampini 
4740e5337592SStefano Zampini       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
4741e5337592SStefano Zampini       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
4742e5337592SStefano Zampini       supportRef[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0;
4743e5337592SStefano Zampini       supportRef[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1;
4744e5337592SStefano Zampini       supportRef[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2;
4745e5337592SStefano Zampini       for (s = 0; s < size; ++s) {
4746e5337592SStefano Zampini         PetscInt r = 0, coneSize;
4747e5337592SStefano Zampini 
4748e5337592SStefano Zampini         ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
4749e5337592SStefano Zampini         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4750e5337592SStefano Zampini         for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;}
4751e5337592SStefano Zampini         supportRef[3+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (support[s] - cStart)*4 + r;
4752e5337592SStefano Zampini       }
4753e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4754e5337592SStefano Zampini #if 1
4755e5337592SStefano Zampini       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
4756e5337592SStefano Zampini       for (p = 0; p < 3+size; ++p) {
4757e5337592SStefano 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);
4758e5337592SStefano Zampini       }
4759e5337592SStefano Zampini #endif
4760e5337592SStefano Zampini     }
4761e5337592SStefano Zampini     /* Interior cell vertices have 4 supports */
4762e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
4763e5337592SStefano Zampini       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + c - cStart;
4764e5337592SStefano Zampini       supportRef[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
4765e5337592SStefano Zampini       supportRef[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
4766e5337592SStefano Zampini       supportRef[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
4767e5337592SStefano Zampini       supportRef[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
4768e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4769e5337592SStefano Zampini #if 1
4770e5337592SStefano Zampini       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
4771e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4772e5337592SStefano 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);
4773e5337592SStefano Zampini       }
4774e5337592SStefano Zampini #endif
4775e5337592SStefano Zampini     }
4776e5337592SStefano Zampini     ierr = PetscFree(supportRef);CHKERRQ(ierr);
4777e5337592SStefano Zampini     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
4778e5337592SStefano Zampini     break;
47799b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
47802eabf88fSMatthew G. Knepley     /*
47812eabf88fSMatthew G. Knepley      Bottom (viewed from top)    Top
47822eabf88fSMatthew G. Knepley      1---------2---------2       7---------2---------6
47832eabf88fSMatthew G. Knepley      |         |         |       |         |         |
47842eabf88fSMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
47852eabf88fSMatthew G. Knepley      |         |         |       |         |         |
47862eabf88fSMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
47872eabf88fSMatthew G. Knepley      |         |         |       |         |         |
47882eabf88fSMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
47892eabf88fSMatthew G. Knepley      |         |         |       |         |         |
47902eabf88fSMatthew G. Knepley      0---------0---------3       4---------0---------5
47912eabf88fSMatthew G. Knepley      */
47922eabf88fSMatthew G. Knepley     /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
47932eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
47942eabf88fSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
47952eabf88fSMatthew G. Knepley       const PetscInt *cone, *ornt;
47962eabf88fSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
47972eabf88fSMatthew G. Knepley 
47982eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
47992eabf88fSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
48002eabf88fSMatthew G. Knepley       /* A hex */
4801e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
48022eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
48032eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
48042eabf88fSMatthew G. Knepley       orntNew[1] = 0;
4805e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
48062eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
48072eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
48082eabf88fSMatthew G. Knepley       orntNew[3] = 0;
48092eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
48102eabf88fSMatthew G. Knepley       orntNew[4] = 0;
4811e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
48122eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
48132eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
48142eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
48152eabf88fSMatthew G. Knepley #if 1
48162eabf88fSMatthew 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);
48172eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
48182eabf88fSMatthew 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);
48192eabf88fSMatthew G. Knepley       }
48202eabf88fSMatthew G. Knepley #endif
48212eabf88fSMatthew G. Knepley       /* B hex */
4822e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
48232eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
48242eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
48252eabf88fSMatthew G. Knepley       orntNew[1] = 0;
48262eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
4827a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
4828e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
48292eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
48302eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
48312eabf88fSMatthew G. Knepley       orntNew[4] = 0;
4832e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
48332eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
48342eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
48352eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
48362eabf88fSMatthew G. Knepley #if 1
48372eabf88fSMatthew 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);
48382eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
48392eabf88fSMatthew 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);
48402eabf88fSMatthew G. Knepley       }
48412eabf88fSMatthew G. Knepley #endif
48422eabf88fSMatthew G. Knepley       /* C hex */
4843e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
48442eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
48452eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
48462eabf88fSMatthew G. Knepley       orntNew[1] = 0;
48472eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
4848a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
4849e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
48502eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
4851e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
48522eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
48532eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
4854a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
48552eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
48562eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
48572eabf88fSMatthew G. Knepley #if 1
48582eabf88fSMatthew 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);
48592eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
48602eabf88fSMatthew 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);
48612eabf88fSMatthew G. Knepley       }
48622eabf88fSMatthew G. Knepley #endif
48632eabf88fSMatthew G. Knepley       /* D hex */
4864e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
48652eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
48662eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
48672eabf88fSMatthew G. Knepley       orntNew[1] = 0;
4868e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
48692eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
48702eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
4871a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4872e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
48732eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
48742eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
4875a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
48762eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
48772eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
48782eabf88fSMatthew G. Knepley #if 1
48792eabf88fSMatthew 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);
48802eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
48812eabf88fSMatthew 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);
48822eabf88fSMatthew G. Knepley       }
48832eabf88fSMatthew G. Knepley #endif
48842eabf88fSMatthew G. Knepley       /* E hex */
48852eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
4886a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
4887e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
48882eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
4889e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
48902eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
48912eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
48922eabf88fSMatthew G. Knepley       orntNew[3] = 0;
48932eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
4894a3cddbf8SMatthew G. Knepley       orntNew[4] = -1;
4895e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
48962eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
4897b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
4898b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
48992eabf88fSMatthew G. Knepley #if 1
4900b164cbf2SMatthew 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);
49012eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
49022eabf88fSMatthew 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);
49032eabf88fSMatthew G. Knepley       }
49042eabf88fSMatthew G. Knepley #endif
49052eabf88fSMatthew G. Knepley       /* F hex */
49062eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
4907a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
4908e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
49092eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
4910e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
49112eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
49122eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
4913a3cddbf8SMatthew G. Knepley       orntNew[3] = -1;
4914e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
49152eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
49162eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
4917a3cddbf8SMatthew G. Knepley       orntNew[5] = 1;
4918b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
4919b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
49202eabf88fSMatthew G. Knepley #if 1
4921b164cbf2SMatthew 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);
49222eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
49232eabf88fSMatthew 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);
49242eabf88fSMatthew G. Knepley       }
49252eabf88fSMatthew G. Knepley #endif
49262eabf88fSMatthew G. Knepley       /* G hex */
49272eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
4928a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
4929e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
49302eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
49312eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
4932a3cddbf8SMatthew G. Knepley       orntNew[2] = 0;
4933e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
49342eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
4935e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
49362eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
49372eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
4938a3cddbf8SMatthew G. Knepley       orntNew[5] = -3;
4939b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
4940b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
49412eabf88fSMatthew G. Knepley #if 1
4942b164cbf2SMatthew 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);
49432eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
49442eabf88fSMatthew 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);
49452eabf88fSMatthew G. Knepley       }
49462eabf88fSMatthew G. Knepley #endif
49472eabf88fSMatthew G. Knepley       /* H hex */
49482eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
4949a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
4950e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
49512eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
49522eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
4953a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
4954e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
49552eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
49562eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
4957a3cddbf8SMatthew G. Knepley       orntNew[4] = 3;
4958e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
49592eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
4960b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
4961b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
49622eabf88fSMatthew G. Knepley #if 1
4963b164cbf2SMatthew 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);
49642eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
49652eabf88fSMatthew 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);
49662eabf88fSMatthew G. Knepley       }
49672eabf88fSMatthew G. Knepley #endif
49682eabf88fSMatthew G. Knepley     }
49692eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
49702eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
4971854ce69bSBarry Smith     ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
49722eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
49732eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
4974aaebbb9dSMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
49752eabf88fSMatthew 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};
49762eabf88fSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
49772eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
4978aaebbb9dSMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
49792eabf88fSMatthew G. Knepley 
49802eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
4981aaebbb9dSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
4982a3cddbf8SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
4983a3cddbf8SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
4984a3cddbf8SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
4985a3cddbf8SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
4986a3cddbf8SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
4987a3cddbf8SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
4988a3cddbf8SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4;
4989a3cddbf8SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
49902eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4991aaebbb9dSMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
49922eabf88fSMatthew G. Knepley #if 1
49932eabf88fSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
49942eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
49952eabf88fSMatthew 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);
49962eabf88fSMatthew G. Knepley         }
49972eabf88fSMatthew G. Knepley #endif
49982eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
49992eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
50002eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
50012eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
50022eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
50032eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
50042eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
50052eabf88fSMatthew G. Knepley             if (cone[c] == f) break;
50062eabf88fSMatthew G. Knepley           }
5007a3cddbf8SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)];
50082eabf88fSMatthew G. Knepley         }
50092eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
50102eabf88fSMatthew G. Knepley #if 1
50112eabf88fSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
50122eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
50132eabf88fSMatthew 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);
50142eabf88fSMatthew G. Knepley         }
50152eabf88fSMatthew G. Knepley #endif
50162eabf88fSMatthew G. Knepley       }
50172eabf88fSMatthew G. Knepley     }
50182eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
50192eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
50202eabf88fSMatthew 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};
5021afb2665bSMatthew G. Knepley       const PetscInt *cone, *ornt;
5022afb2665bSMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
50232eabf88fSMatthew G. Knepley 
50242eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
5025afb2665bSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
5026afb2665bSMatthew G. Knepley       /* A-D face */
5027afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0;
5028a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
5029a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
5030a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
5031afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5032a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
5033a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
5034a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
5035afb2665bSMatthew G. Knepley       orntNew[3] = -2;
50362eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5037afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
50382eabf88fSMatthew G. Knepley #if 1
50392eabf88fSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
50402eabf88fSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
50412eabf88fSMatthew 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);
50422eabf88fSMatthew G. Knepley       }
50432eabf88fSMatthew G. Knepley #endif
5044afb2665bSMatthew G. Knepley       /* C-D face */
5045afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1;
5046a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
5047a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
5048a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
5049afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5050a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
5051a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
5052a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
5053afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5054afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5055afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5056afb2665bSMatthew G. Knepley #if 1
5057afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5058afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5059afb2665bSMatthew 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);
5060afb2665bSMatthew G. Knepley       }
5061afb2665bSMatthew G. Knepley #endif
5062afb2665bSMatthew G. Knepley       /* B-C face */
5063afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2;
5064afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
5065afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5066afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
5067afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5068afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
5069afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5070afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
5071afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5072afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5073afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5074afb2665bSMatthew G. Knepley #if 1
5075afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5076afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5077afb2665bSMatthew 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);
5078afb2665bSMatthew G. Knepley       }
5079afb2665bSMatthew G. Knepley #endif
5080afb2665bSMatthew G. Knepley       /* A-B face */
5081afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3;
5082afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
5083afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5084afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
5085afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5086afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
5087afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5088afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
5089afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5090afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5091afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5092afb2665bSMatthew G. Knepley #if 1
5093afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5094afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5095afb2665bSMatthew 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);
5096afb2665bSMatthew G. Knepley       }
5097afb2665bSMatthew G. Knepley #endif
5098afb2665bSMatthew G. Knepley       /* E-F face */
5099afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4;
5100a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
5101afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5102a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
5103a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
5104a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
5105afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5106a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
5107a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
5108afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5109afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5110afb2665bSMatthew G. Knepley #if 1
5111afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5112afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5113afb2665bSMatthew 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);
5114afb2665bSMatthew G. Knepley       }
5115afb2665bSMatthew G. Knepley #endif
5116afb2665bSMatthew G. Knepley       /* F-G face */
5117afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5;
5118a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
5119afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5120a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
5121a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
5122a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
5123afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5124a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
5125a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
5126afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5127afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5128afb2665bSMatthew G. Knepley #if 1
5129afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5130afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5131afb2665bSMatthew 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);
5132afb2665bSMatthew G. Knepley       }
5133afb2665bSMatthew G. Knepley #endif
5134afb2665bSMatthew G. Knepley       /* G-H face */
5135afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6;
5136afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
5137afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5138afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
5139afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5140afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
5141afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5142afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
5143afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5144afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5145afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5146afb2665bSMatthew G. Knepley #if 1
5147afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5148afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5149afb2665bSMatthew 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);
5150afb2665bSMatthew G. Knepley       }
5151afb2665bSMatthew G. Knepley #endif
5152afb2665bSMatthew G. Knepley       /* E-H face */
5153afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7;
5154a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
5155afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5156a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
5157a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
5158a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
5159afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5160a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
5161a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
5162afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5163afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5164afb2665bSMatthew G. Knepley #if 1
5165afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5166afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5167afb2665bSMatthew 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);
5168afb2665bSMatthew G. Knepley       }
5169afb2665bSMatthew G. Knepley #endif
5170afb2665bSMatthew G. Knepley       /* A-E face */
5171afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8;
5172a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
5173a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
5174a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
5175afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5176a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
5177a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
5178a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
5179afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5180afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5181afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5182afb2665bSMatthew G. Knepley #if 1
5183afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5184afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5185afb2665bSMatthew 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);
5186afb2665bSMatthew G. Knepley       }
5187afb2665bSMatthew G. Knepley #endif
5188afb2665bSMatthew G. Knepley       /* D-F face */
5189afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9;
5190afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
5191afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5192afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
5193afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5194afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
5195afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5196afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
5197afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5198afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5199afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5200afb2665bSMatthew G. Knepley #if 1
5201afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5202afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5203afb2665bSMatthew 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);
5204afb2665bSMatthew G. Knepley       }
5205afb2665bSMatthew G. Knepley #endif
5206afb2665bSMatthew G. Knepley       /* C-G face */
5207afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10;
5208a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
5209afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5210a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
5211a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
5212a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
5213afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5214a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
5215a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
5216afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5217afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5218afb2665bSMatthew G. Knepley #if 1
5219afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5220afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5221afb2665bSMatthew 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);
5222afb2665bSMatthew G. Knepley       }
5223afb2665bSMatthew G. Knepley #endif
5224afb2665bSMatthew G. Knepley       /* B-H face */
5225afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11;
5226a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
5227a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
5228a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
5229a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
5230a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
5231a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
5232a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
5233a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
5234afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5235afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5236afb2665bSMatthew G. Knepley #if 1
5237afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5238afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5239afb2665bSMatthew 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);
5240afb2665bSMatthew G. Knepley       }
5241afb2665bSMatthew G. Knepley #endif
5242afb2665bSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
5243afb2665bSMatthew G. Knepley         newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
52442eabf88fSMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
52452eabf88fSMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
52462eabf88fSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
52472eabf88fSMatthew G. Knepley #if 1
52482eabf88fSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
52492eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
52502eabf88fSMatthew 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);
52512eabf88fSMatthew G. Knepley         }
52522eabf88fSMatthew G. Knepley #endif
52532eabf88fSMatthew G. Knepley       }
52542eabf88fSMatthew G. Knepley     }
52552eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
52562eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
52572eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
52582eabf88fSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
52592eabf88fSMatthew G. Knepley 
52602eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
52612eabf88fSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
52622eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
52632eabf88fSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
52642eabf88fSMatthew G. Knepley 
52652eabf88fSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
52662eabf88fSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
52672eabf88fSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
52682eabf88fSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
52692eabf88fSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
52702eabf88fSMatthew G. Knepley #if 1
52712eabf88fSMatthew 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);
52722eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
52732eabf88fSMatthew 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);
52742eabf88fSMatthew G. Knepley         }
52752eabf88fSMatthew G. Knepley #endif
52762eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
52772eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
52782eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
52792eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
52802eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
52812eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
52822eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
52832eabf88fSMatthew G. Knepley             if (cone[c] == e) break;
52842eabf88fSMatthew G. Knepley           }
52852eabf88fSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
52862eabf88fSMatthew G. Knepley         }
52872eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
52882eabf88fSMatthew G. Knepley #if 1
52892eabf88fSMatthew 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);
52902eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
52912eabf88fSMatthew 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);
52922eabf88fSMatthew G. Knepley         }
52932eabf88fSMatthew G. Knepley #endif
52942eabf88fSMatthew G. Knepley       }
52952eabf88fSMatthew G. Knepley     }
52962eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
52972eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
52986b852384SMatthew 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};
52992eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
53006b852384SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
53012eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
53022eabf88fSMatthew G. Knepley 
53032eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
53042eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
53052eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
53062eabf88fSMatthew G. Knepley 
53072eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
53082eabf88fSMatthew G. Knepley         coneNew[1] = newv;
53092eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
53102eabf88fSMatthew G. Knepley #if 1
53112eabf88fSMatthew 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);
53122eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
53132eabf88fSMatthew 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);
53142eabf88fSMatthew G. Knepley         }
53152eabf88fSMatthew G. Knepley #endif
53162eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
53172eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
53182eabf88fSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
53192eabf88fSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
53202eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
53216b852384SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
53226b852384SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
53236b852384SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
53242eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
5325a3cddbf8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
53262eabf88fSMatthew G. Knepley         }
53272eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
53282eabf88fSMatthew G. Knepley #if 1
53292eabf88fSMatthew 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);
53302eabf88fSMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
53312eabf88fSMatthew 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);
53322eabf88fSMatthew G. Knepley         }
53332eabf88fSMatthew G. Knepley #endif
53342eabf88fSMatthew G. Knepley       }
53352eabf88fSMatthew G. Knepley     }
53362eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
53372eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
53382eabf88fSMatthew 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};
53392eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
53402eabf88fSMatthew G. Knepley       const PetscInt *cone;
53412eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
53422eabf88fSMatthew G. Knepley 
53432eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
53442eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
53452eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
53462eabf88fSMatthew G. Knepley 
53472eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
53482eabf88fSMatthew G. Knepley         coneNew[1] = newv;
53492eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
53502eabf88fSMatthew G. Knepley #if 1
53512eabf88fSMatthew 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);
53522eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
53532eabf88fSMatthew 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);
53542eabf88fSMatthew G. Knepley         }
53552eabf88fSMatthew G. Knepley #endif
53562eabf88fSMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
53572eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
53582eabf88fSMatthew G. Knepley #if 1
53592eabf88fSMatthew 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);
53602eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
53612eabf88fSMatthew 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);
53622eabf88fSMatthew G. Knepley         }
53632eabf88fSMatthew G. Knepley #endif
53642eabf88fSMatthew G. Knepley       }
53652eabf88fSMatthew G. Knepley     }
53662eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
53672eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
53682eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
53692eabf88fSMatthew G. Knepley       const PetscInt *support, *cone;
53702eabf88fSMatthew G. Knepley       PetscInt        size, s;
53712eabf88fSMatthew G. Knepley 
53722eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
53732eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
53742eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
53752eabf88fSMatthew G. Knepley         PetscInt r = 0;
53762eabf88fSMatthew G. Knepley 
53772eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
53782eabf88fSMatthew G. Knepley         if (cone[1] == v) r = 1;
53792eabf88fSMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
53802eabf88fSMatthew G. Knepley       }
53812eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
53822eabf88fSMatthew G. Knepley #if 1
53832eabf88fSMatthew 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);
53842eabf88fSMatthew G. Knepley       for (p = 0; p < size; ++p) {
53852eabf88fSMatthew 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);
53862eabf88fSMatthew G. Knepley       }
53872eabf88fSMatthew G. Knepley #endif
53882eabf88fSMatthew G. Knepley     }
53892eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
53902eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
53912eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
53922eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
53932eabf88fSMatthew G. Knepley       PetscInt        size, s;
53942eabf88fSMatthew G. Knepley 
53952eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
53962eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
53972eabf88fSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
53982eabf88fSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
53992eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
54002eabf88fSMatthew G. Knepley         PetscInt r;
54012eabf88fSMatthew G. Knepley 
54022eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
5403a660e16cSMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
54042eabf88fSMatthew G. Knepley         supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r;
54052eabf88fSMatthew G. Knepley       }
54062eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
54072eabf88fSMatthew G. Knepley #if 1
54082eabf88fSMatthew 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);
54092eabf88fSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
54102eabf88fSMatthew 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);
54112eabf88fSMatthew G. Knepley       }
54122eabf88fSMatthew G. Knepley #endif
54132eabf88fSMatthew G. Knepley     }
54142eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
54152eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
54162eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
54172eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
54182eabf88fSMatthew G. Knepley       PetscInt        size, s;
54192eabf88fSMatthew G. Knepley 
54202eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
54212eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
54220793999aSMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 +  (f - fStart)*4 + r;
54232eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
54242eabf88fSMatthew G. Knepley         PetscInt r;
54252eabf88fSMatthew G. Knepley 
54262eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
54272eabf88fSMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
54282eabf88fSMatthew G. Knepley         supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r;
54292eabf88fSMatthew G. Knepley       }
54302eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
54312eabf88fSMatthew G. Knepley #if 1
54322eabf88fSMatthew 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);
54332eabf88fSMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
54342eabf88fSMatthew 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);
54352eabf88fSMatthew G. Knepley       }
54362eabf88fSMatthew G. Knepley #endif
54372eabf88fSMatthew G. Knepley     }
54382eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
54392eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
54402eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
54412eabf88fSMatthew G. Knepley       PetscInt       supportNew[6];
54422eabf88fSMatthew G. Knepley 
54432eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
54442eabf88fSMatthew G. Knepley         supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
54452eabf88fSMatthew G. Knepley       }
54462eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
54472eabf88fSMatthew G. Knepley     }
5448da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
54492eabf88fSMatthew G. Knepley     break;
54509b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
545127fcede3SMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
545227fcede3SMatthew G. Knepley     /*
545327fcede3SMatthew G. Knepley      Bottom (viewed from top)    Top
545427fcede3SMatthew G. Knepley      1---------2---------2       7---------2---------6
545527fcede3SMatthew G. Knepley      |         |         |       |         |         |
545627fcede3SMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
545727fcede3SMatthew G. Knepley      |         |         |       |         |         |
545827fcede3SMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
545927fcede3SMatthew G. Knepley      |         |         |       |         |         |
546027fcede3SMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
546127fcede3SMatthew G. Knepley      |         |         |       |         |         |
546227fcede3SMatthew G. Knepley      0---------0---------3       4---------0---------5
546327fcede3SMatthew G. Knepley      */
546427fcede3SMatthew G. Knepley     /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
546527fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
546627fcede3SMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
546727fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
546827fcede3SMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
546927fcede3SMatthew G. Knepley 
547027fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
547127fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
547227fcede3SMatthew G. Knepley       /* A hex */
547327fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
547427fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
547527fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
547627fcede3SMatthew G. Knepley       orntNew[1] = 0;
547727fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
547827fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
547927fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
548027fcede3SMatthew G. Knepley       orntNew[3] = 0;
548127fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
548227fcede3SMatthew G. Knepley       orntNew[4] = 0;
548327fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
548427fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
548527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
548627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
548727fcede3SMatthew G. Knepley #if 1
548827fcede3SMatthew 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);
548927fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
549027fcede3SMatthew 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);
549127fcede3SMatthew G. Knepley       }
549227fcede3SMatthew G. Knepley #endif
549327fcede3SMatthew G. Knepley       /* B hex */
549427fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
549527fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
549627fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
549727fcede3SMatthew G. Knepley       orntNew[1] = 0;
549827fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
549927fcede3SMatthew G. Knepley       orntNew[2] = -1;
550027fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
550127fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
550227fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
550327fcede3SMatthew G. Knepley       orntNew[4] = 0;
550427fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
550527fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
550627fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
550727fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
550827fcede3SMatthew G. Knepley #if 1
550927fcede3SMatthew 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);
551027fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
551127fcede3SMatthew 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);
551227fcede3SMatthew G. Knepley       }
551327fcede3SMatthew G. Knepley #endif
551427fcede3SMatthew G. Knepley       /* C hex */
551527fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
551627fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
551727fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
551827fcede3SMatthew G. Knepley       orntNew[1] = 0;
551927fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
552027fcede3SMatthew G. Knepley       orntNew[2] = -1;
552127fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
552227fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
552327fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
552427fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
552527fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
552627fcede3SMatthew G. Knepley       orntNew[5] = -4;
552727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
552827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
552927fcede3SMatthew G. Knepley #if 1
553027fcede3SMatthew 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);
553127fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
553227fcede3SMatthew 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);
553327fcede3SMatthew G. Knepley       }
553427fcede3SMatthew G. Knepley #endif
553527fcede3SMatthew G. Knepley       /* D hex */
553627fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
553727fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
553827fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
553927fcede3SMatthew G. Knepley       orntNew[1] = 0;
554027fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
554127fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
554227fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
554327fcede3SMatthew G. Knepley       orntNew[3] = 0;
554427fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
554527fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
554627fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
554727fcede3SMatthew G. Knepley       orntNew[5] = -4;
554827fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
554927fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
555027fcede3SMatthew G. Knepley #if 1
555127fcede3SMatthew 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);
555227fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
555327fcede3SMatthew 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);
555427fcede3SMatthew G. Knepley       }
555527fcede3SMatthew G. Knepley #endif
555627fcede3SMatthew G. Knepley       /* E hex */
555727fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
555827fcede3SMatthew G. Knepley       orntNew[0] = -4;
555927fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
556027fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
556127fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
556227fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
556327fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
556427fcede3SMatthew G. Knepley       orntNew[3] = 0;
556527fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
556627fcede3SMatthew G. Knepley       orntNew[4] = -1;
556727fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
556827fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
556927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
557027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
557127fcede3SMatthew G. Knepley #if 1
557227fcede3SMatthew 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);
557327fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
557427fcede3SMatthew 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);
557527fcede3SMatthew G. Knepley       }
557627fcede3SMatthew G. Knepley #endif
557727fcede3SMatthew G. Knepley       /* F hex */
557827fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
557927fcede3SMatthew G. Knepley       orntNew[0] = -4;
558027fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
558127fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
558227fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
558327fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
558427fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
558527fcede3SMatthew G. Knepley       orntNew[3] = -1;
558627fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
558727fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
558827fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
558927fcede3SMatthew G. Knepley       orntNew[5] = 1;
559027fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
559127fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
559227fcede3SMatthew G. Knepley #if 1
559327fcede3SMatthew 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);
559427fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
559527fcede3SMatthew 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);
559627fcede3SMatthew G. Knepley       }
559727fcede3SMatthew G. Knepley #endif
559827fcede3SMatthew G. Knepley       /* G hex */
559927fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
560027fcede3SMatthew G. Knepley       orntNew[0] = -4;
560127fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
560227fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
560327fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
560427fcede3SMatthew G. Knepley       orntNew[2] = 0;
560527fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
560627fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
560727fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
560827fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
560927fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
561027fcede3SMatthew G. Knepley       orntNew[5] = -3;
561127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
561227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
561327fcede3SMatthew G. Knepley #if 1
561427fcede3SMatthew 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);
561527fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
561627fcede3SMatthew 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);
561727fcede3SMatthew G. Knepley       }
561827fcede3SMatthew G. Knepley #endif
561927fcede3SMatthew G. Knepley       /* H hex */
562027fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
562127fcede3SMatthew G. Knepley       orntNew[0] = -4;
562227fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
562327fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
562427fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
562527fcede3SMatthew G. Knepley       orntNew[2] = -1;
562627fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
562727fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
562827fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
562927fcede3SMatthew G. Knepley       orntNew[4] = 3;
563027fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
563127fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
563227fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
563327fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
563427fcede3SMatthew G. Knepley #if 1
563527fcede3SMatthew 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);
563627fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
563727fcede3SMatthew 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);
563827fcede3SMatthew G. Knepley       }
563927fcede3SMatthew G. Knepley #endif
564027fcede3SMatthew G. Knepley     }
564127fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces: Front, Back, Sides */
564227fcede3SMatthew G. Knepley     /*
564327fcede3SMatthew G. Knepley      3---------2---------2
564427fcede3SMatthew G. Knepley      |         |         |
564527fcede3SMatthew G. Knepley      |    D    2    C    |
564627fcede3SMatthew G. Knepley      |         |         |
564727fcede3SMatthew G. Knepley      3----3----0----1----1
564827fcede3SMatthew G. Knepley      |         |         |
564927fcede3SMatthew G. Knepley      |    A    0    B    |
565027fcede3SMatthew G. Knepley      |         |         |
565127fcede3SMatthew G. Knepley      0---------0---------1
565227fcede3SMatthew G. Knepley      */
565327fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
565427fcede3SMatthew G. Knepley       const PetscInt  newp = (cMax - cStart)*8 + (c - cMax)*4;
565527fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
5656d273725eSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6], o, of, i;
565727fcede3SMatthew G. Knepley 
565827fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
565927fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
566027fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
5661d273725eSMatthew G. Knepley       o = ornt[0] < 0 ? -1 : 1;
566227fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
566327fcede3SMatthew G. Knepley         PetscInt subfA = GetQuadSubface_Static(ornt[0], r);
566427fcede3SMatthew G. Knepley         PetscInt edgeA = GetQuadEdge_Static(ornt[0], r);
5665d273725eSMatthew G. Knepley         PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4);
566627fcede3SMatthew 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]);
566727fcede3SMatthew G. Knepley         coneNew[0]         = fStartNew + (cone[0] - fStart)*4 + subfA;
566827fcede3SMatthew G. Knepley         orntNew[0]         = ornt[0];
566927fcede3SMatthew G. Knepley         coneNew[1]         = fStartNew + (cone[1] - fStart)*4 + subfA;
567027fcede3SMatthew G. Knepley         orntNew[1]         = ornt[0];
5671d273725eSMatthew G. Knepley         of = fornt[edgeA] < 0 ? -1 : 1;
5672d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], r) + 2;
5673d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0);
5674d273725eSMatthew G. Knepley         orntNew[i] = ornt[edgeA];
5675d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2;
5676d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeA;
5677d273725eSMatthew G. Knepley         orntNew[i] = 0;
5678d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2;
5679d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeB;
5680d273725eSMatthew G. Knepley         orntNew[i] = -2;
5681d273725eSMatthew G. Knepley         of = fornt[edgeB] < 0 ? -1 : 1;
5682d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2;
5683d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1);
5684d273725eSMatthew G. Knepley         orntNew[i] = ornt[edgeB];
568527fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
568627fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
568727fcede3SMatthew G. Knepley #if 1
568827fcede3SMatthew 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);
568927fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
569027fcede3SMatthew 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);
569127fcede3SMatthew G. Knepley         }
569227fcede3SMatthew G. Knepley         for (p = 2; p < 6; ++p) {
569327fcede3SMatthew 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);
569427fcede3SMatthew G. Knepley         }
569527fcede3SMatthew G. Knepley #endif
569627fcede3SMatthew G. Knepley       }
569727fcede3SMatthew G. Knepley     }
569827fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
569927fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
5700854ce69bSBarry Smith     ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
570127fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
570227fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
570327fcede3SMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
570427fcede3SMatthew 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};
570527fcede3SMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
570627fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
570727fcede3SMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
570827fcede3SMatthew G. Knepley 
570927fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
571027fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
571127fcede3SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
571227fcede3SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
571327fcede3SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
571427fcede3SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
571527fcede3SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
571627fcede3SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
571727fcede3SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4;
571827fcede3SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
571927fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
572027fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
572127fcede3SMatthew G. Knepley #if 1
572227fcede3SMatthew 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);
572327fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
572427fcede3SMatthew 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);
572527fcede3SMatthew G. Knepley         }
572627fcede3SMatthew G. Knepley #endif
572727fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
572827fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
572927fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
573027fcede3SMatthew G. Knepley           PetscInt subf;
573127fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
573227fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
573327fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
573427fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
573527fcede3SMatthew G. Knepley             if (cone[c] == f) break;
573627fcede3SMatthew G. Knepley           }
573727fcede3SMatthew G. Knepley           subf = GetQuadSubfaceInverse_Static(ornt[c], r);
573827fcede3SMatthew G. Knepley           if (support[s] < cMax) {
573927fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf];
574027fcede3SMatthew G. Knepley           } else {
574127fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax       - cStart)*8 + (support[s] - cMax)*4 + subf;
574227fcede3SMatthew G. Knepley           }
574327fcede3SMatthew G. Knepley         }
574427fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
574527fcede3SMatthew G. Knepley #if 1
574627fcede3SMatthew 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);
574727fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
574827fcede3SMatthew 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);
574927fcede3SMatthew G. Knepley         }
575027fcede3SMatthew G. Knepley #endif
575127fcede3SMatthew G. Knepley       }
575227fcede3SMatthew G. Knepley     }
5753d273725eSMatthew G. Knepley     /* Interior cell faces have 4 edges and 2 cells */
575427fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
575527fcede3SMatthew 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};
575627fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
575727fcede3SMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
575827fcede3SMatthew G. Knepley 
575927fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
576027fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
576127fcede3SMatthew G. Knepley       /* A-D face */
576227fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0;
576327fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
576427fcede3SMatthew G. Knepley       orntNew[0] = 0;
576527fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
576627fcede3SMatthew G. Knepley       orntNew[1] = 0;
576727fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
576827fcede3SMatthew G. Knepley       orntNew[2] = -2;
576927fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
577027fcede3SMatthew G. Knepley       orntNew[3] = -2;
577127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
577227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
577327fcede3SMatthew G. Knepley #if 1
577427fcede3SMatthew 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);
577527fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
577627fcede3SMatthew 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);
577727fcede3SMatthew G. Knepley       }
577827fcede3SMatthew G. Knepley #endif
577927fcede3SMatthew G. Knepley       /* C-D face */
578027fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1;
578127fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
578227fcede3SMatthew G. Knepley       orntNew[0] = 0;
578327fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
578427fcede3SMatthew G. Knepley       orntNew[1] = 0;
578527fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
578627fcede3SMatthew G. Knepley       orntNew[2] = -2;
578727fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
578827fcede3SMatthew G. Knepley       orntNew[3] = -2;
578927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
579027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
579127fcede3SMatthew G. Knepley #if 1
579227fcede3SMatthew 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);
579327fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
579427fcede3SMatthew 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);
579527fcede3SMatthew G. Knepley       }
579627fcede3SMatthew G. Knepley #endif
579727fcede3SMatthew G. Knepley       /* B-C face */
579827fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2;
579927fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
580027fcede3SMatthew G. Knepley       orntNew[0] = -2;
580127fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
580227fcede3SMatthew G. Knepley       orntNew[1] = 0;
580327fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
580427fcede3SMatthew G. Knepley       orntNew[2] = 0;
580527fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
580627fcede3SMatthew G. Knepley       orntNew[3] = -2;
580727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
580827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
580927fcede3SMatthew G. Knepley #if 1
581027fcede3SMatthew 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);
581127fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
581227fcede3SMatthew 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);
581327fcede3SMatthew G. Knepley       }
581427fcede3SMatthew G. Knepley #endif
581527fcede3SMatthew G. Knepley       /* A-B face */
581627fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3;
581727fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
581827fcede3SMatthew G. Knepley       orntNew[0] = -2;
581927fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
582027fcede3SMatthew G. Knepley       orntNew[1] = 0;
582127fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
582227fcede3SMatthew G. Knepley       orntNew[2] = 0;
582327fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
582427fcede3SMatthew G. Knepley       orntNew[3] = -2;
582527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
582627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
582727fcede3SMatthew G. Knepley #if 1
582827fcede3SMatthew 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);
582927fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
583027fcede3SMatthew 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);
583127fcede3SMatthew G. Knepley       }
583227fcede3SMatthew G. Knepley #endif
583327fcede3SMatthew G. Knepley       /* E-F face */
583427fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4;
583527fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
583627fcede3SMatthew G. Knepley       orntNew[0] = -2;
583727fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
583827fcede3SMatthew G. Knepley       orntNew[1] = -2;
583927fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
584027fcede3SMatthew G. Knepley       orntNew[2] = 0;
584127fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
584227fcede3SMatthew G. Knepley       orntNew[3] = 0;
584327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
584427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
584527fcede3SMatthew G. Knepley #if 1
584627fcede3SMatthew 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);
584727fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
584827fcede3SMatthew 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);
584927fcede3SMatthew G. Knepley       }
585027fcede3SMatthew G. Knepley #endif
585127fcede3SMatthew G. Knepley       /* F-G face */
585227fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5;
585327fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
585427fcede3SMatthew G. Knepley       orntNew[0] = -2;
585527fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
585627fcede3SMatthew G. Knepley       orntNew[1] = -2;
585727fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
585827fcede3SMatthew G. Knepley       orntNew[2] = 0;
585927fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
586027fcede3SMatthew G. Knepley       orntNew[3] = 0;
586127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
586227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
586327fcede3SMatthew G. Knepley #if 1
586427fcede3SMatthew 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);
586527fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
586627fcede3SMatthew 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);
586727fcede3SMatthew G. Knepley       }
586827fcede3SMatthew G. Knepley #endif
586927fcede3SMatthew G. Knepley       /* G-H face */
587027fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6;
587127fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
587227fcede3SMatthew G. Knepley       orntNew[0] = -2;
587327fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
587427fcede3SMatthew G. Knepley       orntNew[1] = 0;
587527fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
587627fcede3SMatthew G. Knepley       orntNew[2] = 0;
587727fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
587827fcede3SMatthew G. Knepley       orntNew[3] = -2;
587927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
588027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
588127fcede3SMatthew G. Knepley #if 1
588227fcede3SMatthew 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);
588327fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
588427fcede3SMatthew 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);
588527fcede3SMatthew G. Knepley       }
588627fcede3SMatthew G. Knepley #endif
588727fcede3SMatthew G. Knepley       /* E-H face */
588827fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7;
588927fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
589027fcede3SMatthew G. Knepley       orntNew[0] = -2;
589127fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
589227fcede3SMatthew G. Knepley       orntNew[1] = -2;
589327fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
589427fcede3SMatthew G. Knepley       orntNew[2] = 0;
589527fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
589627fcede3SMatthew G. Knepley       orntNew[3] = 0;
589727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
589827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
589927fcede3SMatthew G. Knepley #if 1
590027fcede3SMatthew 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);
590127fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
590227fcede3SMatthew 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);
590327fcede3SMatthew G. Knepley       }
590427fcede3SMatthew G. Knepley #endif
590527fcede3SMatthew G. Knepley       /* A-E face */
590627fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8;
590727fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
590827fcede3SMatthew G. Knepley       orntNew[0] = 0;
590927fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
591027fcede3SMatthew G. Knepley       orntNew[1] = 0;
591127fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
591227fcede3SMatthew G. Knepley       orntNew[2] = -2;
591327fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
591427fcede3SMatthew G. Knepley       orntNew[3] = -2;
591527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
591627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
591727fcede3SMatthew G. Knepley #if 1
591827fcede3SMatthew 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);
591927fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
592027fcede3SMatthew 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);
592127fcede3SMatthew G. Knepley       }
592227fcede3SMatthew G. Knepley #endif
592327fcede3SMatthew G. Knepley       /* D-F face */
592427fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9;
592527fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
592627fcede3SMatthew G. Knepley       orntNew[0] = -2;
592727fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
592827fcede3SMatthew G. Knepley       orntNew[1] = 0;
592927fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
593027fcede3SMatthew G. Knepley       orntNew[2] = 0;
593127fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
593227fcede3SMatthew G. Knepley       orntNew[3] = -2;
593327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
593427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
593527fcede3SMatthew G. Knepley #if 1
593627fcede3SMatthew 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);
593727fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
593827fcede3SMatthew 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);
593927fcede3SMatthew G. Knepley       }
594027fcede3SMatthew G. Knepley #endif
594127fcede3SMatthew G. Knepley       /* C-G face */
594227fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10;
594327fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
594427fcede3SMatthew G. Knepley       orntNew[0] = -2;
594527fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
594627fcede3SMatthew G. Knepley       orntNew[1] = -2;
594727fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
594827fcede3SMatthew G. Knepley       orntNew[2] = 0;
594927fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
595027fcede3SMatthew G. Knepley       orntNew[3] = 0;
595127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
595227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
595327fcede3SMatthew G. Knepley #if 1
595427fcede3SMatthew 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);
595527fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
595627fcede3SMatthew 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);
595727fcede3SMatthew G. Knepley       }
595827fcede3SMatthew G. Knepley #endif
595927fcede3SMatthew G. Knepley       /* B-H face */
596027fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11;
596127fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
596227fcede3SMatthew G. Knepley       orntNew[0] = 0;
596327fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
596427fcede3SMatthew G. Knepley       orntNew[1] = -2;
596527fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
596627fcede3SMatthew G. Knepley       orntNew[2] = -2;
596727fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
596827fcede3SMatthew G. Knepley       orntNew[3] = 0;
596927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
597027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
597127fcede3SMatthew G. Knepley #if 1
597227fcede3SMatthew 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);
597327fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
597427fcede3SMatthew 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);
597527fcede3SMatthew G. Knepley       }
597627fcede3SMatthew G. Knepley #endif
597727fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
597827fcede3SMatthew G. Knepley         newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
597927fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
598027fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
598127fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
598227fcede3SMatthew G. Knepley #if 1
598327fcede3SMatthew 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);
598427fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
598527fcede3SMatthew 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);
598627fcede3SMatthew G. Knepley         }
598727fcede3SMatthew G. Knepley #endif
598827fcede3SMatthew G. Knepley       }
598927fcede3SMatthew G. Knepley     }
599027fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
599127fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
599227fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
599327fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
599427fcede3SMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
599527fcede3SMatthew G. Knepley 
599627fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
599727fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
599827fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
599927fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
600027fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
600127fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
600227fcede3SMatthew G. Knepley 
600327fcede3SMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
600427fcede3SMatthew G. Knepley         orntNew[0]   = ornt[0];
600527fcede3SMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
600627fcede3SMatthew G. Knepley         orntNew[1]   = ornt[1];
600727fcede3SMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax);
600827fcede3SMatthew G. Knepley         orntNew[2+r] = 0;
600927fcede3SMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd      - eMax) + (f - fMax);
601027fcede3SMatthew G. Knepley         orntNew[3-r] = 0;
601127fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
601227fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
601327fcede3SMatthew G. Knepley #if 1
601427fcede3SMatthew 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);
601527fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
601627fcede3SMatthew 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);
601727fcede3SMatthew G. Knepley         }
601827fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
601927fcede3SMatthew 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);
602027fcede3SMatthew G. Knepley         }
602127fcede3SMatthew G. Knepley #endif
602227fcede3SMatthew G. Knepley         for (s = 0; s < size; ++s) {
602327fcede3SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
6024d273725eSMatthew G. Knepley           PetscInt        o, of;
602527fcede3SMatthew G. Knepley 
602627fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
602727fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
6028d273725eSMatthew G. Knepley           o = orntCell[0] < 0 ? -1 : 1;
602927fcede3SMatthew G. Knepley           for (c = 2; c < 6; ++c) if (coneCell[c] == f) break;
603027fcede3SMatthew 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]);
603127fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
6032d273725eSMatthew G. Knepley           of = fornt[c-2] < 0 ? -1 : 1;
6033d273725eSMatthew 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;
603427fcede3SMatthew G. Knepley         }
603527fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
603627fcede3SMatthew G. Knepley #if 1
603727fcede3SMatthew 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);
603827fcede3SMatthew G. Knepley         for (p = 0; p < size; ++p) {
603927fcede3SMatthew 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);
604027fcede3SMatthew G. Knepley         }
604127fcede3SMatthew G. Knepley #endif
604227fcede3SMatthew G. Knepley       }
604327fcede3SMatthew G. Knepley     }
604427fcede3SMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
604527fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
604627fcede3SMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4;
604727fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
604827fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
604927fcede3SMatthew G. Knepley       PetscInt        supportNew[2];
605027fcede3SMatthew G. Knepley 
605127fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
605227fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
605327fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
6054d273725eSMatthew G. Knepley #if 0
605527fcede3SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r);
605627fcede3SMatthew G. Knepley         orntNew[0] = 0;
605727fcede3SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r);
605827fcede3SMatthew G. Knepley         orntNew[1] = 0;
605927fcede3SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax);
606027fcede3SMatthew G. Knepley         orntNew[2] = 0;
606127fcede3SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd                                   - fMax) + (c - cMax);
606227fcede3SMatthew G. Knepley         orntNew[3] = 0;
6063d273725eSMatthew G. Knepley #else
6064d273725eSMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r;
6065d273725eSMatthew G. Knepley         orntNew[0] = 0;
6066d273725eSMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r;
6067d273725eSMatthew G. Knepley         orntNew[1] = 0;
6068d273725eSMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax);
6069d273725eSMatthew G. Knepley         orntNew[2] = 0;
6070d273725eSMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd      - fMax) + (c - cMax);
6071d273725eSMatthew G. Knepley         orntNew[3] = 0;
6072d273725eSMatthew G. Knepley #endif
607327fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
607427fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
607527fcede3SMatthew G. Knepley #if 1
607627fcede3SMatthew 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);
607727fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
607827fcede3SMatthew 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);
607927fcede3SMatthew G. Knepley         }
608027fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
608127fcede3SMatthew 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);
608227fcede3SMatthew G. Knepley         }
608327fcede3SMatthew G. Knepley #endif
608427fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r);
608527fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4);
608627fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
608727fcede3SMatthew G. Knepley #if 1
608827fcede3SMatthew 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);
608927fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
609027fcede3SMatthew 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);
609127fcede3SMatthew G. Knepley         }
609227fcede3SMatthew G. Knepley #endif
609327fcede3SMatthew G. Knepley       }
609427fcede3SMatthew G. Knepley     }
609527fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
609627fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
609727fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
609827fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
609927fcede3SMatthew G. Knepley 
610027fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
610127fcede3SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
610227fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
610327fcede3SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
610427fcede3SMatthew G. Knepley 
610527fcede3SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
610627fcede3SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
610727fcede3SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
610827fcede3SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
610927fcede3SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
611027fcede3SMatthew G. Knepley #if 1
611127fcede3SMatthew 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);
611227fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
611327fcede3SMatthew 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);
611427fcede3SMatthew G. Knepley         }
611527fcede3SMatthew G. Knepley #endif
611627fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
611727fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
611827fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
611927fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
612027fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
612127fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
612227fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
612327fcede3SMatthew G. Knepley             if (cone[c] == e) break;
612427fcede3SMatthew G. Knepley           }
612527fcede3SMatthew G. Knepley           if (support[s] < fMax) {
612627fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4;
612727fcede3SMatthew G. Knepley           } else {
612827fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
612927fcede3SMatthew G. Knepley           }
613027fcede3SMatthew G. Knepley         }
613127fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
613227fcede3SMatthew G. Knepley #if 1
613327fcede3SMatthew 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);
613427fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
613527fcede3SMatthew 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);
613627fcede3SMatthew G. Knepley         }
613727fcede3SMatthew G. Knepley #endif
613827fcede3SMatthew G. Knepley       }
613927fcede3SMatthew G. Knepley     }
614027fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
614127fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
614227fcede3SMatthew 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};
614327fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
614427fcede3SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
614527fcede3SMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
614627fcede3SMatthew G. Knepley 
614727fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
614827fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
614927fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
615027fcede3SMatthew G. Knepley 
615127fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
615227fcede3SMatthew G. Knepley         coneNew[1] = newv;
615327fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
615427fcede3SMatthew G. Knepley #if 1
615527fcede3SMatthew 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);
615627fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
615727fcede3SMatthew 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);
615827fcede3SMatthew G. Knepley         }
615927fcede3SMatthew G. Knepley #endif
616027fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
616127fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
616227fcede3SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
616327fcede3SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
616427fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
616527fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
616627fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
616727fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
616827fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
616927fcede3SMatthew G. Knepley           if (support[s] < cMax) {
617027fcede3SMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
617127fcede3SMatthew G. Knepley           } else {
6172d273725eSMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r;
617327fcede3SMatthew G. Knepley           }
617427fcede3SMatthew G. Knepley         }
617527fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
617627fcede3SMatthew G. Knepley #if 1
617727fcede3SMatthew 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);
617827fcede3SMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
617927fcede3SMatthew 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);
618027fcede3SMatthew G. Knepley         }
618127fcede3SMatthew G. Knepley #endif
618227fcede3SMatthew G. Knepley       }
618327fcede3SMatthew G. Knepley     }
618427fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
618527fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
618627fcede3SMatthew 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};
618727fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
618827fcede3SMatthew G. Knepley       const PetscInt *cone;
618927fcede3SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
619027fcede3SMatthew G. Knepley 
619127fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
619227fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
619327fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
619427fcede3SMatthew G. Knepley 
619527fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart);
619627fcede3SMatthew G. Knepley         coneNew[1] = newv;
619727fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
619827fcede3SMatthew G. Knepley #if 1
619927fcede3SMatthew 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);
620027fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
620127fcede3SMatthew 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);
620227fcede3SMatthew G. Knepley         }
620327fcede3SMatthew G. Knepley #endif
620427fcede3SMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
620527fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
620627fcede3SMatthew G. Knepley #if 1
620727fcede3SMatthew 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);
620827fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
620927fcede3SMatthew 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);
621027fcede3SMatthew G. Knepley         }
621127fcede3SMatthew G. Knepley #endif
621227fcede3SMatthew G. Knepley       }
621327fcede3SMatthew G. Knepley     }
621427fcede3SMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
621527fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
621627fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
621727fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
621827fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
621927fcede3SMatthew G. Knepley 
622027fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
622127fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
622227fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
622327fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
622427fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
622527fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
622627fcede3SMatthew G. Knepley #if 1
622727fcede3SMatthew 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);
622827fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
622927fcede3SMatthew 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);
623027fcede3SMatthew G. Knepley       }
623127fcede3SMatthew G. Knepley #endif
623227fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
623327fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
623427fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
623527fcede3SMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
623627fcede3SMatthew 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]);
623727fcede3SMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2;
623827fcede3SMatthew G. Knepley       }
623927fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
624027fcede3SMatthew G. Knepley #if 1
624127fcede3SMatthew 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);
624227fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
624327fcede3SMatthew 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);
624427fcede3SMatthew G. Knepley       }
624527fcede3SMatthew G. Knepley #endif
624627fcede3SMatthew G. Knepley     }
624727fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
624827fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
624927fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
625027fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
625127fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
625227fcede3SMatthew G. Knepley 
625327fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
625427fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
625527fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
625627fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
625727fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
625827fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
625927fcede3SMatthew G. Knepley #if 1
626027fcede3SMatthew 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);
626127fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
626227fcede3SMatthew 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);
626327fcede3SMatthew G. Knepley       }
626427fcede3SMatthew G. Knepley #endif
626527fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0;
626627fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1;
626727fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
626827fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
626927fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
627027fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
627127fcede3SMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
627227fcede3SMatthew 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]);
6273d273725eSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2;
627427fcede3SMatthew G. Knepley       }
627527fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
627627fcede3SMatthew G. Knepley #if 1
627727fcede3SMatthew 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);
627827fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
627927fcede3SMatthew 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);
628027fcede3SMatthew G. Knepley       }
628127fcede3SMatthew G. Knepley #endif
628227fcede3SMatthew G. Knepley     }
628327fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
628427fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
628527fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
628627fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
628727fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size;
628827fcede3SMatthew G. Knepley 
628927fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
629027fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr);
629127fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr);
629227fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart);
629327fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart);
629427fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
629527fcede3SMatthew G. Knepley #if 1
629627fcede3SMatthew 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);
629727fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
629827fcede3SMatthew 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);
629927fcede3SMatthew G. Knepley       }
630027fcede3SMatthew G. Knepley #endif
630127fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0;
630227fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1;
630327fcede3SMatthew G. Knepley       supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2;
630427fcede3SMatthew G. Knepley       supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3;
630527fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
630627fcede3SMatthew G. Knepley #if 1
630727fcede3SMatthew 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);
630827fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
630927fcede3SMatthew 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);
631027fcede3SMatthew G. Knepley       }
631127fcede3SMatthew G. Knepley #endif
631227fcede3SMatthew G. Knepley     }
631327fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
631427fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
631527fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
631627fcede3SMatthew G. Knepley       const PetscInt *support, *cone;
631727fcede3SMatthew G. Knepley       PetscInt        size, s;
631827fcede3SMatthew G. Knepley 
631927fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
632027fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
632127fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
632227fcede3SMatthew G. Knepley         PetscInt r = 0;
632327fcede3SMatthew G. Knepley 
632427fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
632527fcede3SMatthew G. Knepley         if (cone[1] == v) r = 1;
632627fcede3SMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
632727fcede3SMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax);
632827fcede3SMatthew G. Knepley       }
632927fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
633027fcede3SMatthew G. Knepley #if 1
633127fcede3SMatthew 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);
633227fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
633327fcede3SMatthew 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);
633427fcede3SMatthew G. Knepley       }
633527fcede3SMatthew G. Knepley #endif
633627fcede3SMatthew G. Knepley     }
633727fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
633827fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
633927fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
634027fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
634127fcede3SMatthew G. Knepley       PetscInt        size, s;
634227fcede3SMatthew G. Knepley 
634327fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
634427fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
634527fcede3SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
634627fcede3SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
634727fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
634827fcede3SMatthew G. Knepley         PetscInt r;
634927fcede3SMatthew G. Knepley 
635027fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
635127fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
635227fcede3SMatthew G. Knepley         if (support[s] < fMax) {
635327fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r;
635427fcede3SMatthew G. Knepley         } else {
635527fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax);
635627fcede3SMatthew G. Knepley         }
635727fcede3SMatthew G. Knepley       }
635827fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
635927fcede3SMatthew G. Knepley #if 1
636027fcede3SMatthew 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);
636127fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
636227fcede3SMatthew 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);
636327fcede3SMatthew G. Knepley       }
636427fcede3SMatthew G. Knepley #endif
636527fcede3SMatthew G. Knepley     }
636627fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
636727fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
636827fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
636927fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
637027fcede3SMatthew G. Knepley       PetscInt        size, s;
637127fcede3SMatthew G. Knepley 
637227fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
637327fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
637427fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 +  (f - fStart)*4 + r;
637527fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
637627fcede3SMatthew G. Knepley         PetscInt r;
637727fcede3SMatthew G. Knepley 
637827fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
637927fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
638027fcede3SMatthew G. Knepley         if (support[s] < cMax) {
638127fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r;
638227fcede3SMatthew G. Knepley         } else {
638327fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax       - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax);
638427fcede3SMatthew G. Knepley         }
638527fcede3SMatthew G. Knepley       }
638627fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
638727fcede3SMatthew G. Knepley #if 1
638827fcede3SMatthew 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);
638927fcede3SMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
639027fcede3SMatthew 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);
639127fcede3SMatthew G. Knepley       }
639227fcede3SMatthew G. Knepley #endif
639327fcede3SMatthew G. Knepley     }
639427fcede3SMatthew G. Knepley     /* Cell vertices have 6 supports */
639527fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
639627fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
639727fcede3SMatthew G. Knepley       PetscInt       supportNew[6];
639827fcede3SMatthew G. Knepley 
639927fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
640027fcede3SMatthew G. Knepley         supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
640127fcede3SMatthew G. Knepley       }
640227fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
640327fcede3SMatthew G. Knepley     }
640427fcede3SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
640527fcede3SMatthew G. Knepley     break;
640675d3a19aSMatthew G. Knepley   default:
640775d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
640875d3a19aSMatthew G. Knepley   }
640975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
641075d3a19aSMatthew G. Knepley }
641175d3a19aSMatthew G. Knepley 
641286150812SJed Brown static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
641375d3a19aSMatthew G. Knepley {
641475d3a19aSMatthew G. Knepley   PetscSection          coordSection, coordSectionNew;
641575d3a19aSMatthew G. Knepley   Vec                   coordinates, coordinatesNew;
641675d3a19aSMatthew G. Knepley   PetscScalar          *coords, *coordsNew;
64173478d7aaSMatthew G. Knepley   const PetscInt        numVertices = depthSize ? depthSize[0] : 0;
641890b157c4SStefano Zampini   PetscInt              dim, spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax;
641990b157c4SStefano Zampini   PetscInt              c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f;
64209fc2a3f3SStefano Zampini   PetscInt              cStartNew, cEndNew, vEndNew, *parentId = NULL;
64218b9ced59SLisandro Dalcin   VecType               vtype;
64229fc2a3f3SStefano Zampini   PetscBool             isperiodic, localize = PETSC_FALSE, needcoords = PETSC_FALSE;
642390b157c4SStefano Zampini   const PetscReal      *maxCell, *L;
642490b157c4SStefano Zampini   const DMBoundaryType *bd;
642575d3a19aSMatthew G. Knepley   PetscErrorCode        ierr;
642675d3a19aSMatthew G. Knepley 
642775d3a19aSMatthew G. Knepley   PetscFunctionBegin;
6428a57030b0SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
642975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
643075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
6431b5da9499SMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
643275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
643375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
643427fcede3SMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr);
643590b157c4SStefano Zampini   ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, NULL, NULL, &vStartNew);CHKERRQ(ierr);
643690b157c4SStefano Zampini   ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, NULL, NULL, &vEndNew);CHKERRQ(ierr);
6437f719d809SMatthew G. Knepley   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
6438f1d7821bSLawrence Mitchell   ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr);
643975d3a19aSMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr);
644075d3a19aSMatthew G. Knepley   ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr);
6441f1d7821bSLawrence Mitchell   ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr);
644290b157c4SStefano Zampini   ierr = DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);CHKERRQ(ierr);
644390b157c4SStefano Zampini   ierr = DMSetPeriodicity(rdm, isperiodic,  maxCell,  L,  bd);CHKERRQ(ierr);
644490b157c4SStefano Zampini   /* Determine if we need to localize coordinates when generating them */
64459fc2a3f3SStefano Zampini   if (isperiodic && !maxCell) {
64469fc2a3f3SStefano Zampini     ierr = DMGetCoordinatesLocalized(dm, &localize);CHKERRQ(ierr);
64479fc2a3f3SStefano Zampini     if (!localize) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot refine if coordinates have not been localized");
64489fc2a3f3SStefano Zampini   }
644990b157c4SStefano Zampini   if (localize) {
645090b157c4SStefano Zampini     PetscInt p, r, newp, *pi;
645190b157c4SStefano Zampini 
645290b157c4SStefano Zampini     /* New coordinates will be already localized on the cell */
645390b157c4SStefano Zampini     ierr = PetscSectionSetChart(coordSectionNew, 0, vStartNew+numVertices);CHKERRQ(ierr);
645490b157c4SStefano Zampini 
645590b157c4SStefano Zampini     /* We need the parentId to properly localize coordinates */
645690b157c4SStefano Zampini     ierr = PetscMalloc1(cEndNew-cStartNew,&pi);CHKERRQ(ierr);
645790b157c4SStefano Zampini     switch (refiner) {
645890b157c4SStefano Zampini     case REFINER_NOOP:
645990b157c4SStefano Zampini       break;
646090b157c4SStefano Zampini     case REFINER_SIMPLEX_1D:
646190b157c4SStefano Zampini       for (p = cStart; p < cEnd; ++p) {
646290b157c4SStefano Zampini         for (r = 0; r < 2; ++r) {
646390b157c4SStefano Zampini           newp     = (p - cStart)*2 + r;
646490b157c4SStefano Zampini           pi[newp] = p;
646590b157c4SStefano Zampini         }
646690b157c4SStefano Zampini       }
646790b157c4SStefano Zampini       break;
646890b157c4SStefano Zampini     case REFINER_SIMPLEX_2D:
646990b157c4SStefano Zampini       for (p = cStart; p < cEnd; ++p) {
647090b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
647190b157c4SStefano Zampini           newp     = (p - cStart)*4 + r;
647290b157c4SStefano Zampini           pi[newp] = p;
647390b157c4SStefano Zampini         }
647490b157c4SStefano Zampini       }
647590b157c4SStefano Zampini       break;
647690b157c4SStefano Zampini     case REFINER_HEX_2D:
647790b157c4SStefano Zampini       for (p = cStart; p < cEnd; ++p) {
647890b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
647990b157c4SStefano Zampini           newp     = (p - cStart)*4 + r;
648090b157c4SStefano Zampini           pi[newp] = p;
648190b157c4SStefano Zampini         }
648290b157c4SStefano Zampini       }
648390b157c4SStefano Zampini       break;
648490b157c4SStefano Zampini     case REFINER_HYBRID_SIMPLEX_2D:
648590b157c4SStefano Zampini       for (p = cStart; p < cMax; ++p) {
648690b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
648790b157c4SStefano Zampini           newp     = (p - cStart)*4 + r;
648890b157c4SStefano Zampini           pi[newp] = p;
648990b157c4SStefano Zampini         }
649090b157c4SStefano Zampini       }
649190b157c4SStefano Zampini       for (p = cMax; p < cEnd; ++p) {
649290b157c4SStefano Zampini         for (r = 0; r < 2; ++r) {
649390b157c4SStefano Zampini           newp     = (cMax - cStart)*4 + (p - cMax)*2 + r;
649490b157c4SStefano Zampini           pi[newp] = p;
649590b157c4SStefano Zampini         }
649690b157c4SStefano Zampini       }
649790b157c4SStefano Zampini       break;
649890b157c4SStefano Zampini     case REFINER_HYBRID_HEX_2D:
649990b157c4SStefano Zampini       for (p = cStart; p < cMax; ++p) {
650090b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
650190b157c4SStefano Zampini           newp     = (p - cStart)*4 + r;
650290b157c4SStefano Zampini           pi[newp] = p;
650390b157c4SStefano Zampini         }
650490b157c4SStefano Zampini       }
650590b157c4SStefano Zampini       for (p = cMax; p < cEnd; ++p) {
650690b157c4SStefano Zampini         for (r = 0; r < 2; ++r) {
650790b157c4SStefano Zampini           newp     = (cMax - cStart)*4 + (p - cMax)*2 + r;
650890b157c4SStefano Zampini           pi[newp] = p;
650990b157c4SStefano Zampini         }
651090b157c4SStefano Zampini       }
651190b157c4SStefano Zampini       break;
651290b157c4SStefano Zampini     case REFINER_SIMPLEX_3D:
651390b157c4SStefano Zampini       for (p = cStart; p < cEnd; ++p) {
651490b157c4SStefano Zampini         for (r = 0; r < 8; ++r) {
651590b157c4SStefano Zampini           newp     = (p - cStart)*8 + r;
651690b157c4SStefano Zampini           pi[newp] = p;
651790b157c4SStefano Zampini         }
651890b157c4SStefano Zampini       }
651990b157c4SStefano Zampini       break;
652090b157c4SStefano Zampini     case REFINER_HYBRID_SIMPLEX_3D:
652190b157c4SStefano Zampini       for (p = cStart; p < cMax; ++p) {
652290b157c4SStefano Zampini         for (r = 0; r < 8; ++r) {
652390b157c4SStefano Zampini           newp     = (p - cStart)*8 + r;
652490b157c4SStefano Zampini           pi[newp] = p;
652590b157c4SStefano Zampini         }
652690b157c4SStefano Zampini       }
652790b157c4SStefano Zampini       for (p = cMax; p < cEnd; ++p) {
652890b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
652990b157c4SStefano Zampini           newp     = (cMax - cStart)*8 + (p - cMax)*4 + r;
653090b157c4SStefano Zampini           pi[newp] = p;
653190b157c4SStefano Zampini         }
653290b157c4SStefano Zampini       }
653390b157c4SStefano Zampini       break;
653490b157c4SStefano Zampini     case REFINER_HEX_3D:
653590b157c4SStefano Zampini       for (p = cStart; p < cEnd; ++p) {
653690b157c4SStefano Zampini         for (r = 0; r < 8; ++r) {
653790b157c4SStefano Zampini           newp = (p - cStart)*8 + r;
653890b157c4SStefano Zampini           pi[newp] = p;
653990b157c4SStefano Zampini         }
654090b157c4SStefano Zampini       }
654190b157c4SStefano Zampini       break;
654290b157c4SStefano Zampini     case REFINER_HYBRID_HEX_3D:
654390b157c4SStefano Zampini       for (p = cStart; p < cMax; ++p) {
654490b157c4SStefano Zampini         for (r = 0; r < 8; ++r) {
654590b157c4SStefano Zampini           newp = (p - cStart)*8 + r;
654690b157c4SStefano Zampini           pi[newp] = p;
654790b157c4SStefano Zampini         }
654890b157c4SStefano Zampini       }
654990b157c4SStefano Zampini       for (p = cMax; p < cEnd; ++p) {
655090b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
655190b157c4SStefano Zampini           newp = (cMax - cStart)*8 + (p - cMax)*4 + r;
6552451a39c7SStefano Zampini           pi[newp] = p;
655390b157c4SStefano Zampini         }
655490b157c4SStefano Zampini       }
655590b157c4SStefano Zampini       break;
655690b157c4SStefano Zampini     default:
655790b157c4SStefano Zampini       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
655890b157c4SStefano Zampini     }
655990b157c4SStefano Zampini     parentId = pi;
656090b157c4SStefano Zampini   } else {
65613478d7aaSMatthew G. Knepley     ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr);
656290b157c4SStefano Zampini   }
656327fcede3SMatthew G. Knepley   if (cMax < 0) cMax = cEnd;
656475d3a19aSMatthew G. Knepley   if (fMax < 0) fMax = fEnd;
6565b5da9499SMatthew G. Knepley   if (eMax < 0) eMax = eEnd;
656690b157c4SStefano Zampini 
6567f1d7821bSLawrence Mitchell   /* All vertices have the spaceDim coordinates */
656890b157c4SStefano Zampini   if (localize) {
65699fc2a3f3SStefano Zampini     PetscInt c;
657090b157c4SStefano Zampini 
65719fc2a3f3SStefano Zampini     for (c = cStartNew; c < cEndNew; ++c) {
65729fc2a3f3SStefano Zampini       PetscInt *cone = NULL;
65739fc2a3f3SStefano Zampini       PetscInt  closureSize, coneSize = 0, p, pdof;
65749fc2a3f3SStefano Zampini 
65759fc2a3f3SStefano Zampini       ierr = PetscSectionGetDof(coordSection, parentId[c], &pdof); CHKERRQ(ierr);
65769fc2a3f3SStefano Zampini       if (pdof) { /* localize on all cells that are refinement of a localized parent cell */
65779fc2a3f3SStefano Zampini         ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
657890b157c4SStefano Zampini         for (p = 0; p < closureSize*2; p += 2) {
657990b157c4SStefano Zampini           const PetscInt point = cone[p];
658090b157c4SStefano Zampini           if ((point >= vStartNew) && (point < vEndNew)) coneSize++;
658190b157c4SStefano Zampini         }
65829fc2a3f3SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
65839fc2a3f3SStefano Zampini         ierr = PetscSectionSetDof(coordSectionNew, c, coneSize*spaceDim);CHKERRQ(ierr);
65849fc2a3f3SStefano Zampini         ierr = PetscSectionSetFieldDof(coordSectionNew, c, 0, coneSize*spaceDim);CHKERRQ(ierr);
65859fc2a3f3SStefano Zampini       }
658690b157c4SStefano Zampini     }
658790b157c4SStefano Zampini   }
65883478d7aaSMatthew G. Knepley   for (v = vStartNew; v < vStartNew+numVertices; ++v) {
6589f1d7821bSLawrence Mitchell     ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr);
6590f1d7821bSLawrence Mitchell     ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr);
659175d3a19aSMatthew G. Knepley   }
659275d3a19aSMatthew G. Knepley   ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr);
659346e270d4SMatthew G. Knepley   ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr);
659475d3a19aSMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
659575d3a19aSMatthew G. Knepley   ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr);
65968b9ced59SLisandro Dalcin   ierr = VecCreate(PETSC_COMM_SELF, &coordinatesNew);CHKERRQ(ierr);
659775d3a19aSMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr);
659875d3a19aSMatthew G. Knepley   ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr);
659960b9e8a1SMatthew G. Knepley   ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr);
660060b9e8a1SMatthew G. Knepley   ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr);
66018b9ced59SLisandro Dalcin   ierr = VecGetType(coordinates, &vtype);CHKERRQ(ierr);
66028b9ced59SLisandro Dalcin   ierr = VecSetType(coordinatesNew, vtype);CHKERRQ(ierr);
660375d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr);
660475d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
66059fc2a3f3SStefano Zampini 
6606b5da9499SMatthew G. Knepley   switch (refiner) {
66079b1a0e7fSLawrence Mitchell   case REFINER_NOOP: break;
6608e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_3D:
66099b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
66109b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
6611b5da9499SMatthew G. Knepley     /* Face vertices have the average of corner coordinates */
6612d856d60fSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
661327fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
6614b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
6615b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
6616b5da9499SMatthew G. Knepley 
6617b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
6618b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
6619b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
6620b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
6621b5da9499SMatthew G. Knepley       }
662290b157c4SStefano Zampini       if (localize) {
662390b157c4SStefano Zampini         const PetscInt *support = NULL;
662490b157c4SStefano Zampini         PetscInt       *rStar = NULL;
662590b157c4SStefano Zampini         PetscInt        supportSize, rStarSize, coff, s, ccoff[8];
662690b157c4SStefano Zampini         PetscBool       cellfound = PETSC_FALSE;
662790b157c4SStefano Zampini 
662890b157c4SStefano Zampini         ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
662990b157c4SStefano Zampini         ierr = DMPlexGetSupportSize(dm,f,&supportSize);CHKERRQ(ierr);
663090b157c4SStefano Zampini         ierr = DMPlexGetSupport(dm,f,&support);CHKERRQ(ierr);
663190b157c4SStefano Zampini         /* Compute average of coordinates for each cell sharing the face */
663290b157c4SStefano Zampini         for (s = 0; s < supportSize; ++s) {
663390b157c4SStefano Zampini           PetscScalar     coordsNewAux[3] = { 0.0, 0.0, 0.0 };
663490b157c4SStefano Zampini           PetscInt       *cellCone = NULL;
66359fc2a3f3SStefano Zampini           PetscInt        cellClosureSize, cellConeSize = 0, cdof;
663690b157c4SStefano Zampini           const PetscInt  cell = support[s];
663790b157c4SStefano Zampini           PetscBool       copyoff = PETSC_FALSE;
663890b157c4SStefano Zampini 
663990b157c4SStefano Zampini           ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr);
664090b157c4SStefano Zampini           for (p = 0; p < cellClosureSize*2; p += 2) {
664190b157c4SStefano Zampini             const PetscInt point = cellCone[p];
664290b157c4SStefano Zampini             if ((point >= vStart) && (point < vEnd)) cellCone[cellConeSize++] = point;
664390b157c4SStefano Zampini           }
66449fc2a3f3SStefano Zampini           ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr);
66459fc2a3f3SStefano Zampini           if (!cdof) { /* the parent cell does not have localized coordinates */
66469fc2a3f3SStefano Zampini             cellfound = PETSC_TRUE;
66479fc2a3f3SStefano Zampini             for (v = 0; v < coneSize; ++v) {
66489fc2a3f3SStefano Zampini               ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
66499fc2a3f3SStefano Zampini               for (d = 0; d < spaceDim; ++d) coordsNewAux[d] += coords[off[v]+d];
66509fc2a3f3SStefano Zampini             }
66519fc2a3f3SStefano Zampini             for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize;
66529fc2a3f3SStefano Zampini           } else {
66539fc2a3f3SStefano Zampini             ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr);
665490b157c4SStefano Zampini             for (p = 0; p < coneSize; ++p) {
665590b157c4SStefano Zampini               const PetscInt tv = cone[p];
665690b157c4SStefano Zampini               PetscInt       cv, voff;
665790b157c4SStefano Zampini               PetscBool      locv = PETSC_TRUE;
665890b157c4SStefano Zampini 
665990b157c4SStefano Zampini               for (cv = 0; cv < cellConeSize; ++cv) {
666090b157c4SStefano Zampini                 if (cellCone[cv] == tv) {
666190b157c4SStefano Zampini                   ccoff[p] = spaceDim*cv + coff;
666290b157c4SStefano Zampini                   break;
666390b157c4SStefano Zampini                 }
666490b157c4SStefano Zampini               }
666590b157c4SStefano Zampini               if (cv == cellConeSize) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map vertex %D\n",tv);
666690b157c4SStefano Zampini 
666790b157c4SStefano Zampini               ierr = PetscSectionGetOffset(coordSection, cone[p], &voff);CHKERRQ(ierr);
666890b157c4SStefano Zampini               for (d = 0; d < spaceDim; ++d) {
666990b157c4SStefano Zampini                 coordsNewAux[d] += coords[ccoff[p]+d];
667090b157c4SStefano Zampini                 if (!cellfound && coords[voff+d] != coords[ccoff[p]+d]) locv = PETSC_FALSE;
667190b157c4SStefano Zampini               }
667290b157c4SStefano Zampini               if (locv && !cellfound) {
667390b157c4SStefano Zampini                 cellfound = PETSC_TRUE;
667490b157c4SStefano Zampini                 copyoff   = PETSC_TRUE;
667590b157c4SStefano Zampini               }
667690b157c4SStefano Zampini             }
66779fc2a3f3SStefano Zampini             for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize;
667890b157c4SStefano Zampini 
667990b157c4SStefano Zampini             /* Found a valid face for the "vertex" part of the Section (physical space)
668090b157c4SStefano Zampini                i.e., a face that has at least one corner in the physical space */
668190b157c4SStefano Zampini             if (copyoff) for (p = 0; p < coneSize; ++p) off[p] = ccoff[p];
66829fc2a3f3SStefano Zampini           }
668390b157c4SStefano Zampini 
668490b157c4SStefano Zampini           /* Localize new coordinates on each refined cell */
668590b157c4SStefano Zampini           for (v = 0; v < rStarSize*2; v += 2) {
668690b157c4SStefano Zampini             if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew) && parentId[rStar[v]-cStartNew] == cell) {
66879fc2a3f3SStefano Zampini               PetscInt       *rcone = NULL, rclosureSize, lid, rcdof, rcoff;
668890b157c4SStefano Zampini               const PetscInt  rcell = rStar[v];
668990b157c4SStefano Zampini 
66909fc2a3f3SStefano Zampini               ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr);
66919fc2a3f3SStefano Zampini               if (!rcdof) continue;
66929fc2a3f3SStefano Zampini               ierr = PetscSectionGetOffset(coordSectionNew, rcell, &rcoff);CHKERRQ(ierr);
669390b157c4SStefano Zampini               ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr);
669490b157c4SStefano Zampini               for (p = 0, lid = 0; p < rclosureSize*2; p += 2) {
669590b157c4SStefano Zampini                 if (rcone[p] == newv) {
66969fc2a3f3SStefano Zampini                   for (d = 0; d < spaceDim; d++) coordsNew[rcoff + lid*spaceDim + d] = coordsNewAux[d];
669790b157c4SStefano Zampini                   break;
669890b157c4SStefano Zampini                 }
669990b157c4SStefano Zampini                 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++;
670090b157c4SStefano Zampini               }
670190b157c4SStefano Zampini               ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr);
670290b157c4SStefano Zampini               if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv);
670390b157c4SStefano Zampini             }
670490b157c4SStefano Zampini           }
67059fc2a3f3SStefano Zampini           ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr);
670690b157c4SStefano Zampini         }
670790b157c4SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
670890b157c4SStefano Zampini         if (!cellfound) {
67091072f78bSStefano Zampini           /* Could not find a valid face for the vertex part, we will get this vertex later (final reduction) */
67101072f78bSStefano Zampini           needcoords = PETSC_TRUE;
671190b157c4SStefano Zampini           coneSize   = 0;
671290b157c4SStefano Zampini         }
671390b157c4SStefano Zampini       } else {
6714b5da9499SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) {
6715b5da9499SMatthew G. Knepley           ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
6716b5da9499SMatthew G. Knepley         }
671790b157c4SStefano Zampini       }
6718b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
671990b157c4SStefano Zampini       if (coneSize) {
67201072f78bSStefano Zampini         for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
67212e17dfb7SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);}
6722f1d7821bSLawrence Mitchell         for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
67231072f78bSStefano Zampini       } else {
67241072f78bSStefano Zampini         for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL;
672590b157c4SStefano Zampini       }
6726b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
6727b5da9499SMatthew G. Knepley     }
6728e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_2D:
67299b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
67309b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
6731383c10e6SMatthew G. Knepley   case REFINER_SIMPLEX_1D:
6732b5da9499SMatthew G. Knepley     /* Cell vertices have the average of corner coordinates */
673327fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
67342ed5862eSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (dim > 1 ? (eMax - eStart) : 0) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0);
6735b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
67369fc2a3f3SStefano Zampini       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d, cdof = 0;
6737b5da9499SMatthew G. Knepley 
6738b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
6739b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
6740b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
6741b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
6742b5da9499SMatthew G. Knepley       }
674390b157c4SStefano Zampini       if (localize) {
67449fc2a3f3SStefano Zampini         ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr);
67459fc2a3f3SStefano Zampini       }
67469fc2a3f3SStefano Zampini       if (cdof) {
674790b157c4SStefano Zampini         PetscInt coff;
674890b157c4SStefano Zampini 
674990b157c4SStefano Zampini         ierr = PetscSectionGetOffset(coordSection, c, &coff);CHKERRQ(ierr);
675090b157c4SStefano Zampini         for (v = 0; v < coneSize; ++v) off[v] = spaceDim*v + coff;
675190b157c4SStefano Zampini       } else {
6752b5da9499SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) {
6753b5da9499SMatthew G. Knepley           ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
6754b5da9499SMatthew G. Knepley         }
675590b157c4SStefano Zampini       }
6756b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
6757f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
67582e17dfb7SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);}
6759f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
6760b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
67619fc2a3f3SStefano Zampini 
676290b157c4SStefano Zampini       /* Localize new coordinates on each refined cell */
67639fc2a3f3SStefano Zampini       if (cdof) {
676490b157c4SStefano Zampini         PetscInt *rStar = NULL, rStarSize;
676590b157c4SStefano Zampini 
676690b157c4SStefano Zampini         ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
676790b157c4SStefano Zampini         for (v = 0; v < rStarSize*2; v += 2) {
676890b157c4SStefano Zampini           if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew)) {
67699fc2a3f3SStefano Zampini             PetscInt *cone = NULL, closureSize, lid, coff, rc, rcdof;
677090b157c4SStefano Zampini 
677190b157c4SStefano Zampini             rc   = rStar[v];
67729fc2a3f3SStefano Zampini             ierr = PetscSectionGetDof(coordSectionNew, rc, &rcdof);CHKERRQ(ierr);
67739fc2a3f3SStefano Zampini             if (!rcdof) continue;
677490b157c4SStefano Zampini             ierr = PetscSectionGetOffset(coordSectionNew, rc, &coff);CHKERRQ(ierr);
677590b157c4SStefano Zampini             ierr = DMPlexGetTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
677690b157c4SStefano Zampini             for (p = 0, lid = 0; p < closureSize*2; p += 2) {
677790b157c4SStefano Zampini               if (cone[p] == newv) {
677890b157c4SStefano Zampini                 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNew[offnew + d];
677990b157c4SStefano Zampini                 break;
678090b157c4SStefano Zampini               }
678190b157c4SStefano Zampini               if (cone[p] >= vStartNew && cone[p] < vEndNew) lid++;
678290b157c4SStefano Zampini             }
678390b157c4SStefano Zampini             if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv);
678490b157c4SStefano Zampini             ierr = DMPlexRestoreTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
678590b157c4SStefano Zampini           }
678690b157c4SStefano Zampini         }
678790b157c4SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
678890b157c4SStefano Zampini       }
6789b5da9499SMatthew G. Knepley     }
67909b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
67919b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
67929b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
67939b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
6794b5da9499SMatthew G. Knepley     /* Edge vertices have the average of endpoint coordinates */
6795b5da9499SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
6796b5da9499SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (e - eStart);
6797b5da9499SMatthew G. Knepley       const PetscInt *cone;
6798b5da9499SMatthew G. Knepley       PetscInt        coneSize, offA, offB, offnew, d;
6799b5da9499SMatthew G. Knepley 
6800b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr);
6801b5da9499SMatthew G. Knepley       if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize);
6802b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
680390b157c4SStefano Zampini       if (localize) {
68043548e9b6SStefano Zampini         PetscInt   coff, toffA = -1, toffB = -1, voffA, voffB;
680590b157c4SStefano Zampini         PetscInt  *eStar = NULL, eStarSize;
680690b157c4SStefano Zampini         PetscInt  *rStar = NULL, rStarSize;
68079fc2a3f3SStefano Zampini         PetscBool  cellfound = PETSC_FALSE;
680890b157c4SStefano Zampini 
680990b157c4SStefano Zampini         offA = offB = -1;
681090b157c4SStefano Zampini         ierr = PetscSectionGetOffset(coordSection, cone[0], &voffA);CHKERRQ(ierr);
681190b157c4SStefano Zampini         ierr = PetscSectionGetOffset(coordSection, cone[1], &voffB);CHKERRQ(ierr);
681290b157c4SStefano Zampini         ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr);
681390b157c4SStefano Zampini         ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
681490b157c4SStefano Zampini         for (v = 0; v < eStarSize*2; v += 2) {
681590b157c4SStefano Zampini           if ((eStar[v] >= cStart) && (eStar[v] < cEnd)) {
681690b157c4SStefano Zampini             PetscScalar     coordsNewAux[3];
681790b157c4SStefano Zampini             PetscInt       *cellCone = NULL;
68189fc2a3f3SStefano Zampini             PetscInt        cellClosureSize, s, cv, cdof;
681990b157c4SStefano Zampini             PetscBool       locvA = PETSC_TRUE, locvB = PETSC_TRUE;
682090b157c4SStefano Zampini             const PetscInt  cell = eStar[v];
682190b157c4SStefano Zampini 
68229fc2a3f3SStefano Zampini             ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr);
68239fc2a3f3SStefano Zampini             if (!cdof) {
68249fc2a3f3SStefano Zampini               /* Found a valid edge for the "vertex" part of the Section */
68259fc2a3f3SStefano Zampini               offA = voffA;
68269fc2a3f3SStefano Zampini               offB = voffB;
68279fc2a3f3SStefano Zampini               cellfound = PETSC_TRUE;
68289fc2a3f3SStefano Zampini             } else {
682990b157c4SStefano Zampini               ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr);
683090b157c4SStefano Zampini               ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr);
683190b157c4SStefano Zampini               for (s = 0, cv = 0; s < cellClosureSize*2; s += 2) {
683290b157c4SStefano Zampini                 const PetscInt point = cellCone[s];
683390b157c4SStefano Zampini                 if ((point >= vStart) && (point < vEnd)) {
683490b157c4SStefano Zampini                   if (point == cone[0]) toffA = spaceDim*cv + coff;
683590b157c4SStefano Zampini                   else if (point == cone[1]) toffB = spaceDim*cv + coff;
683690b157c4SStefano Zampini                   cv++;
683790b157c4SStefano Zampini                 }
683890b157c4SStefano Zampini               }
683990b157c4SStefano Zampini               ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr);
684090b157c4SStefano Zampini               for (d = 0; d < spaceDim; ++d) {
684190b157c4SStefano Zampini                 coordsNewAux[d] = 0.5*(coords[toffA+d] + coords[toffB+d]);
684290b157c4SStefano Zampini                 if (coords[toffA+d] != coords[voffA+d]) locvA = PETSC_FALSE;
684390b157c4SStefano Zampini                 if (coords[toffB+d] != coords[voffB+d]) locvB = PETSC_FALSE;
684490b157c4SStefano Zampini               }
684590b157c4SStefano Zampini               /* Found a valid edge for the "vertex" part of the Section */
68469fc2a3f3SStefano Zampini               if (!cellfound && (locvA || locvB)) {
68479fc2a3f3SStefano Zampini                 cellfound = PETSC_TRUE;
68489fc2a3f3SStefano Zampini                 offA = toffA;
68499fc2a3f3SStefano Zampini                 offB = toffB;
68509fc2a3f3SStefano Zampini               }
68519fc2a3f3SStefano Zampini             }
685290b157c4SStefano Zampini 
685390b157c4SStefano Zampini             /* Localize new coordinates on each refined cell */
685490b157c4SStefano Zampini             for (s = 0; s < rStarSize*2; s += 2) {
685590b157c4SStefano Zampini               if ((rStar[s] >= cStartNew) && (rStar[s] < cEndNew) && parentId[rStar[s]-cStartNew] == cell) {
68569fc2a3f3SStefano Zampini                 PetscInt       *rcone = NULL, rclosureSize, lid, p, rcdof;
685790b157c4SStefano Zampini                 const PetscInt  rcell = rStar[s];
685890b157c4SStefano Zampini 
68599fc2a3f3SStefano Zampini                 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr);
68609fc2a3f3SStefano Zampini                 if (!rcdof) continue;
686190b157c4SStefano Zampini                 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &coff);CHKERRQ(ierr);
686290b157c4SStefano Zampini                 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr);
686390b157c4SStefano Zampini                 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) {
686490b157c4SStefano Zampini                   if (rcone[p] == newv) {
686590b157c4SStefano Zampini                     for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNewAux[d];
686690b157c4SStefano Zampini                     break;
686790b157c4SStefano Zampini                   }
686890b157c4SStefano Zampini                   if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++;
686990b157c4SStefano Zampini                 }
687090b157c4SStefano Zampini                 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr);
687190b157c4SStefano Zampini                 if (p == rclosureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv);
687290b157c4SStefano Zampini               }
687390b157c4SStefano Zampini             }
687490b157c4SStefano Zampini           }
687590b157c4SStefano Zampini         }
687690b157c4SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr);
687790b157c4SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
68789fc2a3f3SStefano Zampini         if (!cellfound) {
68791072f78bSStefano Zampini           /* Could not find a valid edge for the vertex part, we will get this vertex later (final reduction) */
68801072f78bSStefano Zampini           needcoords = PETSC_TRUE;
688190b157c4SStefano Zampini         }
688290b157c4SStefano Zampini       } else {
6883b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr);
6884b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr);
688590b157c4SStefano Zampini       }
6886b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
688790b157c4SStefano Zampini       if (offA != -1 && offB != -1) {
68882e17dfb7SMatthew G. Knepley         ierr = DMLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr);
6889f1d7821bSLawrence Mitchell         for (d = 0; d < spaceDim; ++d) {
6890a96104c9SMatthew G. Knepley           coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]);
6891b5da9499SMatthew G. Knepley         }
689290b157c4SStefano Zampini       } else {
68931072f78bSStefano Zampini         for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL;
689490b157c4SStefano Zampini       }
6895b5da9499SMatthew G. Knepley     }
689675d3a19aSMatthew G. Knepley     /* Old vertices have the same coordinates */
689775d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
689875d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (v - vStart);
689975d3a19aSMatthew G. Knepley       PetscInt       off, offnew, d;
690075d3a19aSMatthew G. Knepley 
690175d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr);
690275d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
6903f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) {
690475d3a19aSMatthew G. Knepley         coordsNew[offnew+d] = coords[off+d];
690575d3a19aSMatthew G. Knepley       }
690690b157c4SStefano Zampini 
690790b157c4SStefano Zampini       /* Localize new coordinates on each refined cell */
690890b157c4SStefano Zampini       if (localize) {
690990b157c4SStefano Zampini         PetscInt  p;
691090b157c4SStefano Zampini         PetscInt *rStar = NULL, rStarSize;
691190b157c4SStefano Zampini 
691290b157c4SStefano Zampini         ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
691390b157c4SStefano Zampini         for (p = 0; p < rStarSize*2; p += 2) {
691490b157c4SStefano Zampini           if ((rStar[p] >= cStartNew) && (rStar[p] < cEndNew)) {
691590b157c4SStefano Zampini             PetscScalar  ocoords[3];
69169fc2a3f3SStefano Zampini             PetscInt    *cone = NULL, closureSize, lid, coff, s, oc, cdof;
691790b157c4SStefano Zampini 
691890b157c4SStefano Zampini             c    = rStar[p];
691990b157c4SStefano Zampini             oc   = parentId[c-cStartNew];
69209fc2a3f3SStefano Zampini             ierr = PetscSectionGetDof(coordSectionNew, c, &cdof);CHKERRQ(ierr);
69219fc2a3f3SStefano Zampini             if (!cdof) continue;
69229fc2a3f3SStefano Zampini             ierr = PetscSectionGetDof(coordSection, oc, &cdof);CHKERRQ(ierr);
69239fc2a3f3SStefano Zampini             if (!cdof) continue;
692490b157c4SStefano Zampini             ierr = PetscSectionGetOffset(coordSection, oc, &coff);CHKERRQ(ierr);
692590b157c4SStefano Zampini             ierr = DMPlexGetTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
692690b157c4SStefano Zampini             for (s = 0, lid = 0; s < closureSize*2; s += 2) {
692790b157c4SStefano Zampini               if (cone[s] == v) {
692890b157c4SStefano Zampini                 for (d = 0; d < spaceDim; d++) ocoords[d] = coords[coff + lid*spaceDim + d];
692990b157c4SStefano Zampini                 break;
693090b157c4SStefano Zampini               }
693190b157c4SStefano Zampini               if (cone[s] >= vStart && cone[s] < vEnd) lid++;
693290b157c4SStefano Zampini             }
693390b157c4SStefano Zampini             if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map old vertex %D\n",v);
693490b157c4SStefano Zampini             ierr = DMPlexRestoreTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
693590b157c4SStefano Zampini 
693690b157c4SStefano Zampini             ierr = PetscSectionGetOffset(coordSectionNew, c, &coff);CHKERRQ(ierr);
693790b157c4SStefano Zampini             ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
693890b157c4SStefano Zampini             for (s = 0, lid = 0; s < closureSize*2; s += 2) {
693990b157c4SStefano Zampini               if (cone[s] == newv) {
694090b157c4SStefano Zampini                 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = ocoords[d];
694190b157c4SStefano Zampini                 break;
694290b157c4SStefano Zampini               }
694390b157c4SStefano Zampini               if (cone[s] >= vStartNew && cone[s] < vEndNew) lid++;
694490b157c4SStefano Zampini             }
694590b157c4SStefano Zampini             if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv);
694690b157c4SStefano Zampini             ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
694790b157c4SStefano Zampini           }
694890b157c4SStefano Zampini         }
694990b157c4SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
695090b157c4SStefano Zampini       }
695175d3a19aSMatthew G. Knepley     }
6952b5da9499SMatthew G. Knepley     break;
6953b5da9499SMatthew G. Knepley   default:
6954b5da9499SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
695575d3a19aSMatthew G. Knepley   }
695675d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr);
695775d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
695875d3a19aSMatthew G. Knepley   ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr);
695990b157c4SStefano Zampini 
696090b157c4SStefano Zampini   /* Final reduction (if needed) if we are localizing */
696190b157c4SStefano Zampini   if (localize) {
69621072f78bSStefano Zampini     PetscBool gred;
696390b157c4SStefano Zampini 
69641072f78bSStefano Zampini     ierr = MPIU_Allreduce(&needcoords, &gred, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)rdm));CHKERRQ(ierr);
696590b157c4SStefano Zampini     if (gred) {
696690b157c4SStefano Zampini       DM                 cdm;
69671072f78bSStefano Zampini       Vec                aux;
69681072f78bSStefano Zampini       PetscSF            sf;
69691072f78bSStefano Zampini       const PetscScalar *lArray;
69709fc2a3f3SStefano Zampini       PetscScalar       *gArray;
697190b157c4SStefano Zampini 
697290b157c4SStefano Zampini       ierr = DMGetCoordinateDM(rdm, &cdm);CHKERRQ(ierr);
697390b157c4SStefano Zampini       ierr = DMCreateGlobalVector(cdm, &aux);CHKERRQ(ierr);
69741072f78bSStefano Zampini       ierr = DMGetDefaultSF(cdm, &sf);CHKERRQ(ierr);
69751072f78bSStefano Zampini       ierr = VecGetArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr);
69761072f78bSStefano Zampini       ierr = VecSet(aux, PETSC_MIN_REAL);CHKERRQ(ierr);
69771072f78bSStefano Zampini       ierr = VecGetArray(aux, &gArray);CHKERRQ(ierr);
69781072f78bSStefano Zampini       ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr);
69791072f78bSStefano Zampini       ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr);
69801072f78bSStefano Zampini       ierr = VecRestoreArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr);
69811072f78bSStefano Zampini       ierr = VecRestoreArray(aux, &gArray);CHKERRQ(ierr);
698290b157c4SStefano Zampini       ierr = DMGlobalToLocalBegin(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr);
698390b157c4SStefano Zampini       ierr = DMGlobalToLocalEnd(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr);
698490b157c4SStefano Zampini       ierr = VecDestroy(&aux);CHKERRQ(ierr);
698590b157c4SStefano Zampini     }
698690b157c4SStefano Zampini   }
698775d3a19aSMatthew G. Knepley   ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr);
698875d3a19aSMatthew G. Knepley   ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr);
698990b157c4SStefano Zampini   ierr = PetscFree(parentId);CHKERRQ(ierr);
699075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
699175d3a19aSMatthew G. Knepley }
699275d3a19aSMatthew G. Knepley 
6993963fc26aSMatthew G. Knepley /*@
6994963fc26aSMatthew G. Knepley   DMPlexCreateProcessSF - Create an SF which just has process connectivity
6995963fc26aSMatthew G. Knepley 
6996963fc26aSMatthew G. Knepley   Collective on DM
6997963fc26aSMatthew G. Knepley 
6998963fc26aSMatthew G. Knepley   Input Parameters:
6999963fc26aSMatthew G. Knepley + dm      - The DM
7000963fc26aSMatthew G. Knepley - sfPoint - The PetscSF which encodes point connectivity
7001963fc26aSMatthew G. Knepley 
7002963fc26aSMatthew G. Knepley   Output Parameters:
7003963fc26aSMatthew G. Knepley + processRanks - A list of process neighbors, or NULL
7004963fc26aSMatthew G. Knepley - sfProcess    - An SF encoding the process connectivity, or NULL
7005963fc26aSMatthew G. Knepley 
7006963fc26aSMatthew G. Knepley   Level: developer
7007963fc26aSMatthew G. Knepley 
7008963fc26aSMatthew G. Knepley .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF()
7009963fc26aSMatthew G. Knepley @*/
7010963fc26aSMatthew G. Knepley PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
701175d3a19aSMatthew G. Knepley {
701275d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, l;
701375d3a19aSMatthew G. Knepley   const PetscInt    *localPoints;
701475d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
701575d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
701675d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
701775d3a19aSMatthew G. Knepley   PetscInt          *ranks, *ranksNew;
70189852e123SBarry Smith   PetscMPIInt        size;
701975d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
702075d3a19aSMatthew G. Knepley 
702175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
7022963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7023963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2);
7024963fc26aSMatthew G. Knepley   if (processRanks) {PetscValidPointer(processRanks, 3);}
7025963fc26aSMatthew G. Knepley   if (sfProcess)    {PetscValidPointer(sfProcess, 4);}
70269852e123SBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr);
702775d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
7028785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr);
702975d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
703075d3a19aSMatthew G. Knepley     ranks[l] = remotePoints[l].rank;
703175d3a19aSMatthew G. Knepley   }
703275d3a19aSMatthew G. Knepley   ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr);
7033785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr);
7034785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr);
7035785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr);
703675d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
703775d3a19aSMatthew G. Knepley     ranksNew[l]              = ranks[l];
703875d3a19aSMatthew G. Knepley     localPointsNew[l]        = l;
703975d3a19aSMatthew G. Knepley     remotePointsNew[l].index = 0;
704075d3a19aSMatthew G. Knepley     remotePointsNew[l].rank  = ranksNew[l];
704175d3a19aSMatthew G. Knepley   }
704275d3a19aSMatthew G. Knepley   ierr = PetscFree(ranks);CHKERRQ(ierr);
7043963fc26aSMatthew G. Knepley   if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);}
7044963fc26aSMatthew G. Knepley   else              {ierr = PetscFree(ranksNew);CHKERRQ(ierr);}
7045963fc26aSMatthew G. Knepley   if (sfProcess) {
704675d3a19aSMatthew G. Knepley     ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr);
7047963fc26aSMatthew G. Knepley     ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr);
704875d3a19aSMatthew G. Knepley     ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr);
70499852e123SBarry Smith     ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
7050963fc26aSMatthew G. Knepley   }
705175d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
705275d3a19aSMatthew G. Knepley }
705375d3a19aSMatthew G. Knepley 
705486150812SJed Brown static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
705575d3a19aSMatthew G. Knepley {
705675d3a19aSMatthew G. Knepley   PetscSF            sf, sfNew, sfProcess;
705775d3a19aSMatthew G. Knepley   IS                 processRanks;
705875d3a19aSMatthew G. Knepley   MPI_Datatype       depthType;
705975d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, numLeavesNew = 0, l, m;
706075d3a19aSMatthew G. Knepley   const PetscInt    *localPoints, *neighbors;
706175d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
706275d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
706375d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
706475d3a19aSMatthew G. Knepley   PetscInt          *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew;
706537d81139SMatthew G. Knepley   PetscInt           ldepth, depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n;
70667ba685a0SMatthew G. Knepley   PetscInt           cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
706775d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
706875d3a19aSMatthew G. Knepley 
706975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
707075d3a19aSMatthew G. Knepley   ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr);
707137d81139SMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &ldepth);CHKERRQ(ierr);
707237d81139SMatthew G. Knepley   ierr = MPIU_Allreduce(&ldepth, &depth, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr);
707337d81139SMatthew G. Knepley   if ((ldepth >= 0) && (depth != ldepth)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent Plex depth %d != %d", ldepth, depth);
707475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
707575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
707675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
707775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
707875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
7079add09238SMatthew G. Knepley   cMax = cMax < 0 ? cEnd : cMax;
7080add09238SMatthew G. Knepley   fMax = fMax < 0 ? fEnd : fMax;
7081add09238SMatthew G. Knepley   eMax = eMax < 0 ? eEnd : eMax;
70823478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
708375d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
708475d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr);
7085add09238SMatthew G. Knepley   /* Calculate size of new SF */
708675d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
708775d3a19aSMatthew G. Knepley   if (numRoots < 0) PetscFunctionReturn(0);
708875d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
708975d3a19aSMatthew G. Knepley     const PetscInt p = localPoints[l];
709075d3a19aSMatthew G. Knepley 
709175d3a19aSMatthew G. Knepley     switch (refiner) {
70920314a74cSLawrence Mitchell     case REFINER_SIMPLEX_1D:
70930314a74cSLawrence Mitchell       if ((p >= vStart) && (p < vEnd)) {
70940314a74cSLawrence Mitchell         /* Interior vertices stay the same */
70950314a74cSLawrence Mitchell         ++numLeavesNew;
70960314a74cSLawrence Mitchell       } else if ((p >= cStart && p < cMax)) {
70970314a74cSLawrence Mitchell         /* Interior cells add new cells and interior vertices */
70980314a74cSLawrence Mitchell         numLeavesNew += 2 + 1;
70990314a74cSLawrence Mitchell       }
71000314a74cSLawrence Mitchell       break;
71019b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_2D:
71029b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_2D:
7103a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
7104a97b51b8SMatthew G. Knepley         /* Interior vertices stay the same */
7105a97b51b8SMatthew G. Knepley         ++numLeavesNew;
7106a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
7107a97b51b8SMatthew G. Knepley         /* Interior faces add new faces and vertex */
7108a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
7109a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
7110a97b51b8SMatthew G. Knepley         /* Hybrid faces stay the same */
7111a97b51b8SMatthew G. Knepley         ++numLeavesNew;
7112a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
7113a97b51b8SMatthew G. Knepley         /* Interior cells add new cells and interior faces */
7114a97b51b8SMatthew G. Knepley         numLeavesNew += 4 + 3;
7115a97b51b8SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
7116a97b51b8SMatthew G. Knepley         /* Hybrid cells add new cells and hybrid face */
7117a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
7118a97b51b8SMatthew G. Knepley       }
7119a97b51b8SMatthew G. Knepley       break;
7120e5337592SStefano Zampini     case REFINER_SIMPLEX_TO_HEX_2D:
7121e5337592SStefano Zampini       if ((p >= vStart) && (p < vEnd)) {
7122e5337592SStefano Zampini         /* Interior vertices stay the same */
7123e5337592SStefano Zampini         ++numLeavesNew;
7124e5337592SStefano Zampini       } else if ((p >= fStart) && (p < fEnd)) {
7125e5337592SStefano Zampini         /* Interior faces add new faces and vertex */
7126e5337592SStefano Zampini         numLeavesNew += 2 + 1;
7127e5337592SStefano Zampini       } else if ((p >= cStart) && (p < cEnd)) {
7128e5337592SStefano Zampini         /* Interior cells add new cells, interior faces, and vertex */
7129e5337592SStefano Zampini         numLeavesNew += 3 + 3 + 1;
7130e5337592SStefano Zampini       }
7131e5337592SStefano Zampini       break;
71329b1a0e7fSLawrence Mitchell     case REFINER_HEX_2D:
71339b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_2D:
7134a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
7135a97b51b8SMatthew G. Knepley         /* Interior vertices stay the same */
7136a97b51b8SMatthew G. Knepley         ++numLeavesNew;
7137a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
7138a97b51b8SMatthew G. Knepley         /* Interior faces add new faces and vertex */
7139a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
7140a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
7141a97b51b8SMatthew G. Knepley         /* Hybrid faces stay the same */
7142a97b51b8SMatthew G. Knepley         ++numLeavesNew;
7143a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
7144a97b51b8SMatthew G. Knepley         /* Interior cells add new cells, interior faces, and vertex */
7145a97b51b8SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
7146a97b51b8SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
7147a97b51b8SMatthew G. Knepley         /* Hybrid cells add new cells and hybrid face */
7148a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
7149a97b51b8SMatthew G. Knepley       }
7150a97b51b8SMatthew G. Knepley       break;
71519b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_3D:
71529b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_3D:
71536ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
71546ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
71556ce3c06aSMatthew G. Knepley         ++numLeavesNew;
71566ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
71576ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
71586ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
71596ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
71606ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
71616ce3c06aSMatthew G. Knepley         ++numLeavesNew;
71626ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
71636ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
71646ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
71656ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
71666ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
71676ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
71686ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
71696ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
71706ce3c06aSMatthew G. Knepley         numLeavesNew += 8 + 8 + 1;
71716ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
71726ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
71736ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
71746ce3c06aSMatthew G. Knepley       }
71756ce3c06aSMatthew G. Knepley       break;
7176e5337592SStefano Zampini     case REFINER_SIMPLEX_TO_HEX_3D:
7177e5337592SStefano Zampini       if ((p >= vStart) && (p < vEnd)) {
7178e5337592SStefano Zampini         /* Interior vertices stay the same */
7179e5337592SStefano Zampini         ++numLeavesNew;
7180e5337592SStefano Zampini       } else if ((p >= eStart) && (p < eEnd)) {
7181e5337592SStefano Zampini         /* Interior edges add new edges and vertex */
7182e5337592SStefano Zampini         numLeavesNew += 2 + 1;
7183e5337592SStefano Zampini       } else if ((p >= fStart) && (p < fEnd)) {
7184e5337592SStefano Zampini         /* Interior faces add new faces, edges and a vertex */
7185e5337592SStefano Zampini         numLeavesNew += 3 + 3 + 1;
7186e5337592SStefano Zampini       } else if ((p >= cStart) && (p < cEnd)) {
7187e5337592SStefano Zampini         /* Interior cells add new cells, faces, edges and a vertex */
7188e5337592SStefano Zampini         numLeavesNew += 4 + 6 + 4 + 1;
7189e5337592SStefano Zampini       }
7190e5337592SStefano Zampini       break;
71919b1a0e7fSLawrence Mitchell     case REFINER_HEX_3D:
71929b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_3D:
719327fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
719427fcede3SMatthew G. Knepley         /* Old vertices stay the same */
719527fcede3SMatthew G. Knepley         ++numLeavesNew;
719627fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
719727fcede3SMatthew G. Knepley         /* Interior edges add new edges, and vertex */
719827fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
719927fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
720027fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
720127fcede3SMatthew G. Knepley         ++numLeavesNew;
720227fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
720327fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
720427fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
720527fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
720627fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
720727fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
720827fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
720927fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
721027fcede3SMatthew G. Knepley         numLeavesNew += 8 + 12 + 6 + 1;
721127fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
721227fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
721327fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
721427fcede3SMatthew G. Knepley       }
721527fcede3SMatthew G. Knepley       break;
721675d3a19aSMatthew G. Knepley     default:
721775d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
721875d3a19aSMatthew G. Knepley     }
721975d3a19aSMatthew G. Knepley   }
722075d3a19aSMatthew G. Knepley   /* Communicate depthSizes for each remote rank */
722175d3a19aSMatthew G. Knepley   ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr);
722275d3a19aSMatthew G. Knepley   ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr);
7223dcca6d9dSJed Brown   ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr);
7224dcca6d9dSJed Brown   ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr);
722575d3a19aSMatthew G. Knepley   ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr);
722675d3a19aSMatthew G. Knepley   ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr);
722775d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
722875d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
722975d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
723075d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr);
723175d3a19aSMatthew G. Knepley   }
723275d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cMax;
723375d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vMax;
723475d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fMax;
723575d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eMax;
723675d3a19aSMatthew G. Knepley 
723775d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
723875d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
723975d3a19aSMatthew G. Knepley 
724075d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cEnd - cStart;
724175d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vEnd - vStart;
724275d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fEnd - fStart;
724375d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eEnd - eStart;
724475d3a19aSMatthew G. Knepley 
724575d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
724675d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
724775d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
724875d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr);
72490252e7f5SMatthew 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];
72500252e7f5SMatthew 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];
72510252e7f5SMatthew 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];
725275d3a19aSMatthew G. Knepley   }
725375d3a19aSMatthew G. Knepley   ierr = MPI_Type_free(&depthType);CHKERRQ(ierr);
725475d3a19aSMatthew G. Knepley   ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr);
725575d3a19aSMatthew G. Knepley   /* Calculate new point SF */
7256785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr);
7257785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr);
725875d3a19aSMatthew G. Knepley   ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr);
725975d3a19aSMatthew G. Knepley   for (l = 0, m = 0; l < numLeaves; ++l) {
726075d3a19aSMatthew G. Knepley     PetscInt    p     = localPoints[l];
726175d3a19aSMatthew G. Knepley     PetscInt    rp    = remotePoints[l].index, n;
726275d3a19aSMatthew G. Knepley     PetscMPIInt rrank = remotePoints[l].rank;
726375d3a19aSMatthew G. Knepley 
726475d3a19aSMatthew G. Knepley     ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr);
726575d3a19aSMatthew G. Knepley     if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank);
726675d3a19aSMatthew G. Knepley     switch (refiner) {
72670314a74cSLawrence Mitchell     case REFINER_SIMPLEX_1D:
72680314a74cSLawrence Mitchell       if ((p >= vStart) && (p < vEnd)) {
72690314a74cSLawrence Mitchell         /* Old vertices stay the same */
72700314a74cSLawrence Mitchell         localPointsNew[m]        = vStartNew     + (p  - vStart);
72710314a74cSLawrence Mitchell         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
72720314a74cSLawrence Mitchell         remotePointsNew[m].rank  = rrank;
72730314a74cSLawrence Mitchell         ++m;
72740314a74cSLawrence Mitchell       } else if ((p >= cStart) && (p < cMax)) {
72750314a74cSLawrence Mitchell         /* Old interior cells add new cells and vertex */
72760314a74cSLawrence Mitchell         for (r = 0; r < 2; ++r, ++m) {
72770314a74cSLawrence Mitchell           localPointsNew[m]        = cStartNew     + (p  - cStart)*2     + r;
72780314a74cSLawrence Mitchell           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r;
72790314a74cSLawrence Mitchell           remotePointsNew[m].rank  = rrank;
72800314a74cSLawrence Mitchell         }
72810314a74cSLawrence Mitchell         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - cStart);
72820314a74cSLawrence Mitchell         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]);
72830314a74cSLawrence Mitchell         remotePointsNew[m].rank  = rrank;
72840314a74cSLawrence Mitchell         ++m;
72850314a74cSLawrence Mitchell       }
72860314a74cSLawrence Mitchell       break;
72879b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_2D:
72889b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_2D:
728975d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
729075d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
729175d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
729275d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
729375d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
729475d3a19aSMatthew G. Knepley         ++m;
729575d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
729675d3a19aSMatthew G. Knepley         /* Old interior faces add new faces and vertex */
729775d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
729875d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
729975d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
730075d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
730175d3a19aSMatthew G. Knepley         }
7302add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
7303add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
7304add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
7305add09238SMatthew G. Knepley         ++m;
730675d3a19aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
730775d3a19aSMatthew G. Knepley         /* Old hybrid faces stay the same */
730875d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
730975d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
731075d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
731175d3a19aSMatthew G. Knepley         ++m;
731275d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
731375d3a19aSMatthew G. Knepley         /* Old interior cells add new cells and interior faces */
731475d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
731575d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
731675d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
731775d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
731875d3a19aSMatthew G. Knepley         }
731975d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
732075d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*3     + r;
732175d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r;
732275d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
732375d3a19aSMatthew G. Knepley         }
7324add09238SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
732575d3a19aSMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
732675d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
732775d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
732875d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
732975d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
733075d3a19aSMatthew G. Knepley         }
733175d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*3     + (p  - cMax);
733275d3a19aSMatthew 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]);
733375d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
733475d3a19aSMatthew G. Knepley         ++m;
733575d3a19aSMatthew G. Knepley       }
733675d3a19aSMatthew G. Knepley       break;
7337e5337592SStefano Zampini     case REFINER_SIMPLEX_TO_HEX_2D:
7338e5337592SStefano Zampini       if ((p >= vStart) && (p < vEnd)) {
7339e5337592SStefano Zampini         /* Old vertices stay the same */
7340e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (p  - vStart);
7341e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
7342e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7343e5337592SStefano Zampini         ++m;
7344e5337592SStefano Zampini       } else if ((p >= fStart) && (p < fEnd)) {
7345e5337592SStefano Zampini         /* Old interior faces add new faces and vertex */
7346e5337592SStefano Zampini         for (r = 0; r < 2; ++r, ++m) {
7347e5337592SStefano Zampini           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
7348e5337592SStefano Zampini           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
7349e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7350e5337592SStefano Zampini         }
7351e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
7352e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
7353e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7354e5337592SStefano Zampini         ++m;
7355e5337592SStefano Zampini       } else if ((p >= cStart) && (p < cEnd)) {
7356e5337592SStefano Zampini         /* Old interior cells add new cells, interior faces, and a vertex */
7357e5337592SStefano Zampini         for (r = 0; r < 3; ++r, ++m) {
7358e5337592SStefano Zampini           localPointsNew[m]        = cStartNew     + (p  - cStart)*3     + r;
7359e5337592SStefano Zampini           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*3 + r;
7360e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7361e5337592SStefano Zampini         }
7362e5337592SStefano Zampini         for (r = 0; r < 3; ++r, ++m) {
7363e5337592SStefano Zampini           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*2                    + (p  - cStart)*3     + r;
7364e5337592SStefano Zampini           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r;
7365e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7366e5337592SStefano Zampini         }
7367e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (fEnd - fStart)                    + (p  - cStart);
7368e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]);
7369e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7370e5337592SStefano Zampini         ++m;
7371e5337592SStefano Zampini       }
7372e5337592SStefano Zampini       break;
73739b1a0e7fSLawrence Mitchell     case REFINER_HEX_2D:
73749b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_2D:
7375a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
7376a97b51b8SMatthew G. Knepley         /* Old vertices stay the same */
7377a97b51b8SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
7378a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
7379a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
7380a97b51b8SMatthew G. Knepley         ++m;
7381a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
7382a97b51b8SMatthew G. Knepley         /* Old interior faces add new faces and vertex */
7383a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
7384a97b51b8SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
7385a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
7386a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
7387a97b51b8SMatthew G. Knepley         }
7388add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
7389add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
7390add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
7391add09238SMatthew G. Knepley         ++m;
7392a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
7393a97b51b8SMatthew G. Knepley         /* Old hybrid faces stay the same */
7394a97b51b8SMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
7395a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
7396a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
7397a97b51b8SMatthew G. Knepley         ++m;
7398a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
7399a97b51b8SMatthew G. Knepley         /* Old interior cells add new cells, interior faces, and vertex */
7400a97b51b8SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
7401a97b51b8SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
7402a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
7403a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
7404a97b51b8SMatthew G. Knepley         }
7405a97b51b8SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
7406a97b51b8SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*4     + r;
7407a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r;
7408a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
7409a97b51b8SMatthew G. Knepley         }
7410add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)               + (fMax                              - fStart)     + (p  - cStart);
7411add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0]  + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]);
7412add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
7413add09238SMatthew G. Knepley         ++m;
7414a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
7415a97b51b8SMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
7416a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
7417a97b51b8SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
7418a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
7419a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
7420a97b51b8SMatthew G. Knepley         }
7421a97b51b8SMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*4     + (p  - cMax);
7422a97b51b8SMatthew 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]);
7423a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
7424a97b51b8SMatthew G. Knepley         ++m;
7425a97b51b8SMatthew G. Knepley       }
7426a97b51b8SMatthew G. Knepley       break;
74279b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_3D:
74289b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_3D:
74296ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
74306ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
74316ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
74326ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
74336ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
74346ce3c06aSMatthew G. Knepley         ++m;
74356ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
74366ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
74376ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
74386ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
74396ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
74406ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
74416ce3c06aSMatthew G. Knepley         }
74426ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
74436ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
74446ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
74456ce3c06aSMatthew G. Knepley         ++m;
74466ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
74476ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
74486ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (p  - eMax);
74497d5cd7d5SMatthew 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]);
74506ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
74516ce3c06aSMatthew G. Knepley         ++m;
74526ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
74536ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
74546ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
74556ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
74566ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
74576ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
74586ce3c06aSMatthew G. Knepley         }
74596ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
74606ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*3     + r;
74616ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r;
74626ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
74636ce3c06aSMatthew G. Knepley         }
74646ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
74656ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
74666ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
7467899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (p  - fMax)*2                              + r;
7468899f98d0SMatthew 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;
74696ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
74706ce3c06aSMatthew G. Knepley         }
74717d5cd7d5SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (eEnd                                    - eMax)                        + (p  - fMax);
74727d5cd7d5SMatthew 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]);
74736ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
747409b1338fSMatthew G. Knepley         ++m;
74756ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
74766ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
74776ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
74786ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
74796ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
74806ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
74816ce3c06aSMatthew G. Knepley         }
74826ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
74836ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*8     + r;
74846ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r;
74856ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
74866ce3c06aSMatthew G. Knepley         }
7487c7c54c77SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (p  - cStart)*1     + 0;
7488c7c54c77SMatthew 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;
74896ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
749009b1338fSMatthew G. Knepley         ++m;
74916ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
74926ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
74936ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
74946ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
74956ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
74966ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
74976ce3c06aSMatthew G. Knepley         }
74986ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
7499899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (fEnd                                          - fMax)*2                              + (p  - cMax)*3                            + r;
7500899f98d0SMatthew 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;
75016ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
75026ce3c06aSMatthew G. Knepley         }
75036ce3c06aSMatthew G. Knepley       }
75046ce3c06aSMatthew G. Knepley       break;
7505e5337592SStefano Zampini     case REFINER_SIMPLEX_TO_HEX_3D:
7506e5337592SStefano Zampini       if ((p >= vStart) && (p < vEnd)) {
7507e5337592SStefano Zampini         /* Interior vertices stay the same */
7508e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (p  - vStart);
7509e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
7510e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7511e5337592SStefano Zampini         ++m;
7512e5337592SStefano Zampini       } else if ((p >= eStart) && (p < eEnd)) {
7513e5337592SStefano Zampini         /* Interior edges add new edges and vertex */
7514e5337592SStefano Zampini         for (r = 0; r < 2; ++r, ++m) {
7515e5337592SStefano Zampini           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
7516e5337592SStefano Zampini           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
7517e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7518e5337592SStefano Zampini         }
7519e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
7520e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
7521e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7522e5337592SStefano Zampini         ++m;
7523e5337592SStefano Zampini       } else if ((p >= fStart) && (p < fEnd)) {
7524e5337592SStefano Zampini         /* Interior faces add new faces, edges and a vertex */
7525e5337592SStefano Zampini         for (r = 0; r < 3; ++r, ++m) {
7526e5337592SStefano Zampini           localPointsNew[m]        = fStartNew     + (p  - fStart)*3     + r;
7527e5337592SStefano Zampini           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*3 + r;
7528e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7529e5337592SStefano Zampini         }
7530e5337592SStefano Zampini         for (r = 0; r < 3; ++r, ++m) {
7531e5337592SStefano Zampini           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2                + (p  - fStart)*3     + r;
7532e5337592SStefano Zampini           remotePointsNew[m].index = reStartNew[n] + (rdepthSizeOld[n*(depth+1)+1])*2 + (rp - rfStart[n])*3 + r;
7533e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7534e5337592SStefano Zampini         }
7535e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eEnd - eStart)              + (p - fStart);
7536e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]);
7537e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7538e5337592SStefano Zampini         ++m;
7539e5337592SStefano Zampini       } else if ((p >= cStart) && (p < cEnd)) {
7540e5337592SStefano Zampini         /* Interior cells add new cells, faces, edges, and a vertex */
7541e5337592SStefano Zampini         for (r = 0; r < 4; ++r, ++m) {
7542e5337592SStefano Zampini           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
7543e5337592SStefano Zampini           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
7544e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7545e5337592SStefano Zampini         }
7546e5337592SStefano Zampini         for (r = 0; r < 6; ++r, ++m) {
7547e5337592SStefano Zampini           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*3                    + (p  - cStart)*6     + r;
7548e5337592SStefano Zampini           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*6 + r;
7549e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7550e5337592SStefano Zampini         }
7551e5337592SStefano Zampini         for (r = 0; r < 4; ++r, ++m) {
7552e5337592SStefano Zampini           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (fEnd - fStart)*3                    + (p  - cStart)*4 + r;
7553e5337592SStefano Zampini           remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*4 + r;
7554e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7555e5337592SStefano Zampini         }
7556e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eEnd - eStart)              + (fEnd - fStart)                    + (p - cStart);
7557e5337592SStefano 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]);
7558e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7559e5337592SStefano Zampini         ++m;
7560e5337592SStefano Zampini       }
7561e5337592SStefano Zampini       break;
75629b1a0e7fSLawrence Mitchell     case REFINER_HEX_3D:
75639b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_3D:
756427fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
756527fcede3SMatthew G. Knepley         /* Interior vertices stay the same */
756627fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
756727fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
756827fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
756927fcede3SMatthew G. Knepley         ++m;
757027fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
757127fcede3SMatthew G. Knepley         /* Interior edges add new edges and vertex */
757227fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
757327fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
757427fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
757527fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
757627fcede3SMatthew G. Knepley         }
757727fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
757827fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
757927fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
758027fcede3SMatthew G. Knepley         ++m;
758127fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
758227fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
758327fcede3SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (p  - eMax);
7584d2701f60SMatthew 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]);
758527fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
758627fcede3SMatthew G. Knepley         ++m;
758727fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
758827fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
758927fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
759027fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
759127fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
759227fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
759327fcede3SMatthew G. Knepley         }
759427fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
759527fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*4     + r;
759627fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r;
759727fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
759827fcede3SMatthew G. Knepley         }
759927fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eMax                        - eStart)     + (p  - fStart);
760027fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]);
760127fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
760227fcede3SMatthew G. Knepley         ++m;
760327fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
760427fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
760527fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
7606d2701f60SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*12     + (p  - fMax)*2                              + r;
7607d2701f60SMatthew 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;
760827fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
760927fcede3SMatthew G. Knepley         }
7610d2701f60SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (eEnd                                    - eMax)                        + (p  - fMax);
7611d2701f60SMatthew 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]);
761227fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
761327fcede3SMatthew G. Knepley         ++m;
761427fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
761527fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
761627fcede3SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
761727fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
761827fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
761927fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
762027fcede3SMatthew G. Knepley         }
762127fcede3SMatthew G. Knepley         for (r = 0; r < 12; ++r, ++m) {
762227fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*12     + r;
762327fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r;
762427fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
762527fcede3SMatthew G. Knepley         }
762627fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r, ++m) {
762727fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (p  - cStart)*6     + r;
762827fcede3SMatthew 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;
762927fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
763027fcede3SMatthew G. Knepley         }
763127fcede3SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
763227fcede3SMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (eMax                        - eStart)     + (fMax                              - fStart)     + (p  - cStart)     + r;
763327fcede3SMatthew 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;
763427fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
763527fcede3SMatthew G. Knepley         }
763627fcede3SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
763727fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
763827fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
763927fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
764027fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
764127fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
764227fcede3SMatthew G. Knepley         }
764327fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
7644d2701f60SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*12     + (fEnd                                          - fMax)*2                              + (p  - cMax)*4                            + r;
7645d2701f60SMatthew 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;
764627fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
764727fcede3SMatthew G. Knepley         }
7648d2701f60SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (eEnd                                    - eMax)                        + (fEnd                                          - fMax)                              + (p  - cMax);
7649d2701f60SMatthew 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]);
765027fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
765127fcede3SMatthew G. Knepley         ++m;
765227fcede3SMatthew G. Knepley       }
765327fcede3SMatthew G. Knepley       break;
765475d3a19aSMatthew G. Knepley     default:
765575d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
765675d3a19aSMatthew G. Knepley     }
765775d3a19aSMatthew G. Knepley   }
765809b1338fSMatthew G. Knepley   if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew);
765975d3a19aSMatthew G. Knepley   ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr);
766075d3a19aSMatthew G. Knepley   ierr = ISDestroy(&processRanks);CHKERRQ(ierr);
7661ba3c3d50SMatthew G. Knepley   {
7662ba3c3d50SMatthew G. Knepley     PetscSFNode *rp, *rtmp;
7663ba3c3d50SMatthew G. Knepley     PetscInt    *lp, *idx, *ltmp, i;
7664ba3c3d50SMatthew G. Knepley 
7665ba3c3d50SMatthew G. Knepley     /* SF needs sorted leaves to correct calculate Gather */
7666ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr);
7667ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr);
7668ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr);
7669c7c54c77SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
7670c7c54c77SMatthew 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);
7671c7c54c77SMatthew G. Knepley       idx[i] = i;
7672c7c54c77SMatthew G. Knepley     }
7673ba3c3d50SMatthew G. Knepley     ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr);
7674ba3c3d50SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
7675ba3c3d50SMatthew G. Knepley       lp[i] = localPointsNew[idx[i]];
7676ba3c3d50SMatthew G. Knepley       rp[i] = remotePointsNew[idx[i]];
7677ba3c3d50SMatthew G. Knepley     }
7678ba3c3d50SMatthew G. Knepley     ltmp            = localPointsNew;
7679ba3c3d50SMatthew G. Knepley     localPointsNew  = lp;
7680ba3c3d50SMatthew G. Knepley     rtmp            = remotePointsNew;
7681ba3c3d50SMatthew G. Knepley     remotePointsNew = rp;
7682ba3c3d50SMatthew G. Knepley     ierr = PetscFree(idx);CHKERRQ(ierr);
7683ba3c3d50SMatthew G. Knepley     ierr = PetscFree(ltmp);CHKERRQ(ierr);
7684ba3c3d50SMatthew G. Knepley     ierr = PetscFree(rtmp);CHKERRQ(ierr);
7685ba3c3d50SMatthew G. Knepley   }
768675d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
768775d3a19aSMatthew G. Knepley   ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr);
768806a0ba2dSMatthew G. Knepley   ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr);
768975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
769075d3a19aSMatthew G. Knepley }
769175d3a19aSMatthew G. Knepley 
769286150812SJed Brown static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
769375d3a19aSMatthew G. Knepley {
769475d3a19aSMatthew G. Knepley   PetscInt       numLabels, l;
76957ba685a0SMatthew G. Knepley   PetscInt       depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r;
76967ba685a0SMatthew G. Knepley   PetscInt       cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
769775d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
769875d3a19aSMatthew G. Knepley 
769975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
770075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
770175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
770275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
770375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
7704d963de37SMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
77053478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
7706c58f1c22SToby Isaac   ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr);
770775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
770875d3a19aSMatthew G. Knepley   switch (refiner) {
77099b1a0e7fSLawrence Mitchell   case REFINER_NOOP:
77100314a74cSLawrence Mitchell   case REFINER_SIMPLEX_1D:
77119b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
7712e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_2D:
77139b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
77149b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
77159b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
7716e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_3D:
77179b1a0e7fSLawrence Mitchell     break;
77189b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
77199b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
772058b8852aSMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
77219b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
77229b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
772375d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
772475d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
77251e317b1dSMatthew G. Knepley     break;
77269b1a0e7fSLawrence Mitchell   default:
77279b1a0e7fSLawrence Mitchell     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
772875d3a19aSMatthew G. Knepley   }
772975d3a19aSMatthew G. Knepley   for (l = 0; l < numLabels; ++l) {
773075d3a19aSMatthew G. Knepley     DMLabel         label, labelNew;
773175d3a19aSMatthew G. Knepley     const char     *lname;
773275d3a19aSMatthew G. Knepley     PetscBool       isDepth;
773375d3a19aSMatthew G. Knepley     IS              valueIS;
773475d3a19aSMatthew G. Knepley     const PetscInt *values;
77355aa44df4SToby Isaac     PetscInt        defVal;
773675d3a19aSMatthew G. Knepley     PetscInt        numValues, val;
773775d3a19aSMatthew G. Knepley 
7738c58f1c22SToby Isaac     ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr);
773975d3a19aSMatthew G. Knepley     ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr);
774075d3a19aSMatthew G. Knepley     if (isDepth) continue;
7741c58f1c22SToby Isaac     ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr);
7742c58f1c22SToby Isaac     ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr);
7743c58f1c22SToby Isaac     ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr);
77445aa44df4SToby Isaac     ierr = DMLabelGetDefaultValue(label,&defVal);CHKERRQ(ierr);
77455aa44df4SToby Isaac     ierr = DMLabelSetDefaultValue(labelNew,defVal);CHKERRQ(ierr);
774675d3a19aSMatthew G. Knepley     ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr);
774775d3a19aSMatthew G. Knepley     ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr);
774875d3a19aSMatthew G. Knepley     ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr);
774975d3a19aSMatthew G. Knepley     for (val = 0; val < numValues; ++val) {
775075d3a19aSMatthew G. Knepley       IS              pointIS;
775175d3a19aSMatthew G. Knepley       const PetscInt *points;
775275d3a19aSMatthew G. Knepley       PetscInt        numPoints, n;
775375d3a19aSMatthew G. Knepley 
775475d3a19aSMatthew G. Knepley       ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr);
775575d3a19aSMatthew G. Knepley       ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);
775675d3a19aSMatthew G. Knepley       ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr);
77572bc5314cSMichael Lange       /* Ensure refined label is created with same number of strata as
77582bc5314cSMichael Lange        * original (even if no entries here). */
7759ad8374ffSToby Isaac       ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr);
776075d3a19aSMatthew G. Knepley       for (n = 0; n < numPoints; ++n) {
776175d3a19aSMatthew G. Knepley         const PetscInt p = points[n];
776275d3a19aSMatthew G. Knepley         switch (refiner) {
77630314a74cSLawrence Mitchell         case REFINER_SIMPLEX_1D:
77640314a74cSLawrence Mitchell           if ((p >= vStart) && (p < vEnd)) {
77650314a74cSLawrence Mitchell             /* Old vertices stay the same */
77660314a74cSLawrence Mitchell             newp = vStartNew + (p - vStart);
77670314a74cSLawrence Mitchell             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
77680314a74cSLawrence Mitchell           } else if ((p >= cStart) && (p < cEnd)) {
77690314a74cSLawrence Mitchell             /* Old cells add new cells and vertex */
77700314a74cSLawrence Mitchell             newp = vStartNew + (vEnd - vStart) + (p - cStart);
77710314a74cSLawrence Mitchell             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
77720314a74cSLawrence Mitchell             for (r = 0; r < 2; ++r) {
77730314a74cSLawrence Mitchell               newp = cStartNew + (p - cStart)*2 + r;
77740314a74cSLawrence Mitchell               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
77750314a74cSLawrence Mitchell             }
77760314a74cSLawrence Mitchell           }
77770314a74cSLawrence Mitchell           break;
77789b1a0e7fSLawrence Mitchell         case REFINER_SIMPLEX_2D:
777975d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
778075d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
778175d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
778275d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
778375d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
778475d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
778575d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
778675d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
778775d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
778875d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
778975d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
779075d3a19aSMatthew G. Knepley             }
779175d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
779275d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces */
779375d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
779475d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
779575d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
779675d3a19aSMatthew G. Knepley             }
779775d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
779875d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
779975d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
780075d3a19aSMatthew G. Knepley             }
780175d3a19aSMatthew G. Knepley           }
780275d3a19aSMatthew G. Knepley           break;
7803e5337592SStefano Zampini         case REFINER_SIMPLEX_TO_HEX_2D:
7804e5337592SStefano Zampini           if ((p >= vStart) && (p < vEnd)) {
7805e5337592SStefano Zampini             /* Old vertices stay the same */
7806e5337592SStefano Zampini             newp = vStartNew + (p - vStart);
7807e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7808e5337592SStefano Zampini           } else if ((p >= fStart) && (p < fEnd)) {
7809e5337592SStefano Zampini             /* Old faces add new faces and vertex */
7810e5337592SStefano Zampini             newp = vStartNew + (vEnd - vStart) + (p - fStart);
7811e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7812e5337592SStefano Zampini             for (r = 0; r < 2; ++r) {
7813e5337592SStefano Zampini               newp = fStartNew + (p - fStart)*2 + r;
7814e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7815e5337592SStefano Zampini             }
7816e5337592SStefano Zampini           } else if ((p >= cStart) && (p < cEnd)) {
7817e5337592SStefano Zampini             /* Old cells add new cells, interior faces, and a vertex */
7818e5337592SStefano Zampini             for (r = 0; r < 3; ++r) {
7819e5337592SStefano Zampini               newp = cStartNew + (p - cStart)*3 + r;
7820e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7821e5337592SStefano Zampini             }
7822e5337592SStefano Zampini             for (r = 0; r < 3; ++r) {
7823e5337592SStefano Zampini               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
7824e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7825e5337592SStefano Zampini             }
7826e5337592SStefano Zampini             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p;
7827e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7828e5337592SStefano Zampini           }
7829e5337592SStefano Zampini           break;
78309b1a0e7fSLawrence Mitchell         case REFINER_HEX_2D:
783175d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
783275d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
783375d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
783475d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
783575d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
783675d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
783775d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
783875d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
783975d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
784075d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
784175d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
784275d3a19aSMatthew G. Knepley             }
784375d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
784475d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces and vertex */
784575d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
784675d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
784775d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
784875d3a19aSMatthew G. Knepley             }
784975d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
785075d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
785175d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
785275d3a19aSMatthew G. Knepley             }
785375d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
785475d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
785575d3a19aSMatthew G. Knepley           }
785675d3a19aSMatthew G. Knepley           break;
78579b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_SIMPLEX_2D:
785875d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
785975d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
786075d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
786175d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
786275d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
786375d3a19aSMatthew G. Knepley             /* Old interior faces add new faces and vertex */
786475d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
786575d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
786675d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
786775d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
786875d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
786975d3a19aSMatthew G. Knepley             }
787075d3a19aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
787175d3a19aSMatthew G. Knepley             /* Old hybrid faces stay the same */
787275d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
787375d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
787475d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
787575d3a19aSMatthew G. Knepley             /* Old interior cells add new cells and interior faces */
787675d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
787775d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
787875d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
787975d3a19aSMatthew G. Knepley             }
788075d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
788175d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
788275d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
788375d3a19aSMatthew G. Knepley             }
788475d3a19aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
788575d3a19aSMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
788675d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
788775d3a19aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
788875d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
788975d3a19aSMatthew G. Knepley             }
789075d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
789175d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
789275d3a19aSMatthew G. Knepley           }
789375d3a19aSMatthew G. Knepley           break;
78949b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_HEX_2D:
7895a97b51b8SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
7896a97b51b8SMatthew G. Knepley             /* Old vertices stay the same */
7897a97b51b8SMatthew G. Knepley             newp = vStartNew + (p - vStart);
7898a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7899a97b51b8SMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
7900a97b51b8SMatthew G. Knepley             /* Old interior faces add new faces and vertex */
7901a97b51b8SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
7902a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7903a97b51b8SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
7904a97b51b8SMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
7905a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7906a97b51b8SMatthew G. Knepley             }
7907a97b51b8SMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
7908a97b51b8SMatthew G. Knepley             /* Old hybrid faces stay the same */
7909a97b51b8SMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
7910a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7911a97b51b8SMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
7912a97b51b8SMatthew G. Knepley             /* Old interior cells add new cells, interior faces, and vertex */
7913a97b51b8SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
7914a97b51b8SMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
7915a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7916a97b51b8SMatthew G. Knepley             }
7917a97b51b8SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
7918a97b51b8SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
7919a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7920a97b51b8SMatthew G. Knepley             }
7921a97b51b8SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
7922a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7923a97b51b8SMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
7924a97b51b8SMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
7925a97b51b8SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
7926a97b51b8SMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
7927a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7928a97b51b8SMatthew G. Knepley             }
7929a97b51b8SMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax);
7930a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7931a97b51b8SMatthew G. Knepley           }
7932a97b51b8SMatthew G. Knepley           break;
79339b1a0e7fSLawrence Mitchell         case REFINER_SIMPLEX_3D:
7934b5da9499SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
7935b5da9499SMatthew G. Knepley             /* Old vertices stay the same */
7936b5da9499SMatthew G. Knepley             newp = vStartNew + (p - vStart);
7937b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7938b5da9499SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
7939b5da9499SMatthew G. Knepley             /* Old edges add new edges and vertex */
7940b5da9499SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
7941b5da9499SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
7942b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7943b5da9499SMatthew G. Knepley             }
7944b5da9499SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
7945b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7946b5da9499SMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
7947b5da9499SMatthew G. Knepley             /* Old faces add new faces and edges */
7948b5da9499SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
7949b5da9499SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
7950b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7951b5da9499SMatthew G. Knepley             }
7952b5da9499SMatthew G. Knepley             for (r = 0; r < 3; ++r) {
7953b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
7954b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7955b5da9499SMatthew G. Knepley             }
7956b5da9499SMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
7957b5da9499SMatthew G. Knepley             /* Old cells add new cells and interior faces and edges */
7958b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
7959b5da9499SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
7960b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7961b5da9499SMatthew G. Knepley             }
7962b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
7963b5da9499SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r;
7964b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7965b5da9499SMatthew G. Knepley             }
7966b5da9499SMatthew G. Knepley             for (r = 0; r < 1; ++r) {
7967b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r;
7968b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7969b5da9499SMatthew G. Knepley             }
7970b5da9499SMatthew G. Knepley           }
7971b5da9499SMatthew G. Knepley           break;
7972e5337592SStefano Zampini         case REFINER_SIMPLEX_TO_HEX_3D:
7973e5337592SStefano Zampini           if ((p >= vStart) && (p < vEnd)) {
7974e5337592SStefano Zampini             /* Old vertices stay the same */
7975e5337592SStefano Zampini             newp = vStartNew + (p - vStart);
7976e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7977e5337592SStefano Zampini           } else if ((p >= eStart) && (p < eEnd)) {
7978e5337592SStefano Zampini             /* Old edges add new edges and vertex */
7979e5337592SStefano Zampini             for (r = 0; r < 2; ++r) {
7980e5337592SStefano Zampini               newp = eStartNew + (p - eStart)*2 + r;
7981e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7982e5337592SStefano Zampini             }
7983e5337592SStefano Zampini             newp = vStartNew + (vEnd - vStart) + (p - eStart);
7984e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7985e5337592SStefano Zampini           } else if ((p >= fStart) && (p < fEnd)) {
7986e5337592SStefano Zampini             /* Old faces add new faces, edges and a vertex */
7987e5337592SStefano Zampini             for (r = 0; r < 3; ++r) {
7988e5337592SStefano Zampini               newp = fStartNew + (p - fStart)*3 + r;
7989e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7990e5337592SStefano Zampini             }
7991e5337592SStefano Zampini             for (r = 0; r < 3; ++r) {
7992e5337592SStefano Zampini               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
7993e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7994e5337592SStefano Zampini             }
7995e5337592SStefano Zampini           } else if ((p >= cStart) && (p < cEnd)) {
7996e5337592SStefano Zampini             /* Old cells add new cells and interior faces and edges and a vertex */
7997e5337592SStefano Zampini             for (r = 0; r < 4; ++r) {
7998e5337592SStefano Zampini               newp = cStartNew + (p - cStart)*4 + r;
7999e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8000e5337592SStefano Zampini             }
8001e5337592SStefano Zampini             for (r = 0; r < 6; ++r) {
8002e5337592SStefano Zampini               newp = fStartNew + (fEnd - fStart)*3 + (p - cStart)*6 + r;
8003e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8004e5337592SStefano Zampini             }
8005e5337592SStefano Zampini             for (r = 0; r < 4; ++r) {
8006e5337592SStefano Zampini               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*4 + r;
8007e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8008e5337592SStefano Zampini             }
8009e5337592SStefano Zampini             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + p - cStart;
8010e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8011e5337592SStefano Zampini           }
8012e5337592SStefano Zampini           break;
80139b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_SIMPLEX_3D:
80146ce3c06aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
80156ce3c06aSMatthew G. Knepley             /* Interior vertices stay the same */
80166ce3c06aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
80176ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80186ce3c06aSMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
80196ce3c06aSMatthew G. Knepley             /* Interior edges add new edges and vertex */
80206ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
80216ce3c06aSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
80226ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80236ce3c06aSMatthew G. Knepley             }
80246ce3c06aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
80256ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80266ce3c06aSMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
80276ce3c06aSMatthew G. Knepley             /* Hybrid edges stay the same */
80286ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
80296ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80306ce3c06aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
80316ce3c06aSMatthew G. Knepley             /* Interior faces add new faces and edges */
80326ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
80336ce3c06aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
80346ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80356ce3c06aSMatthew G. Knepley             }
80366ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
80376ce3c06aSMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
80386ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80396ce3c06aSMatthew G. Knepley             }
80406ce3c06aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
80416ce3c06aSMatthew G. Knepley             /* Hybrid faces add new faces and edges */
80426ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
80436ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
80446ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80456ce3c06aSMatthew G. Knepley             }
80466ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax);
80476ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80486ce3c06aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
80496ce3c06aSMatthew G. Knepley             /* Interior cells add new cells, faces, and edges */
80506ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
80516ce3c06aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
80526ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80536ce3c06aSMatthew G. Knepley             }
80546ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
80556ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
80566ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80576ce3c06aSMatthew G. Knepley             }
80586ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart);
80596ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
806058b8852aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
80616ce3c06aSMatthew G. Knepley             /* Hybrid cells add new cells and faces */
80626ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
80636ce3c06aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
80646ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80656ce3c06aSMatthew G. Knepley             }
80666ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
80676ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
80686ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80696ce3c06aSMatthew G. Knepley             }
80706ce3c06aSMatthew G. Knepley           }
80716ce3c06aSMatthew G. Knepley           break;
80729b1a0e7fSLawrence Mitchell         case REFINER_HEX_3D:
80732eabf88fSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
80742eabf88fSMatthew G. Knepley             /* Old vertices stay the same */
80752eabf88fSMatthew G. Knepley             newp = vStartNew + (p - vStart);
80762eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
807719d7d790SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
80782eabf88fSMatthew G. Knepley             /* Old edges add new edges and vertex */
80792eabf88fSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
80802eabf88fSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
80812eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80822eabf88fSMatthew G. Knepley             }
80832eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
80842eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80852eabf88fSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
80862eabf88fSMatthew G. Knepley             /* Old faces add new faces, edges, and vertex */
80872eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
80882eabf88fSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
80892eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80902eabf88fSMatthew G. Knepley             }
80912eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
80922eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r;
80932eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80942eabf88fSMatthew G. Knepley             }
80952eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart);
80962eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80972eabf88fSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
80982eabf88fSMatthew G. Knepley             /* Old cells add new cells, faces, edges, and vertex */
80992eabf88fSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
81002eabf88fSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
81012eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
81022eabf88fSMatthew G. Knepley             }
81032eabf88fSMatthew G. Knepley             for (r = 0; r < 12; ++r) {
81042eabf88fSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r;
81052eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
81062eabf88fSMatthew G. Knepley             }
81072eabf88fSMatthew G. Knepley             for (r = 0; r < 6; ++r) {
81082eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r;
81092eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
81102eabf88fSMatthew G. Knepley             }
81112eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart);
81122eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
81132eabf88fSMatthew G. Knepley           }
81142eabf88fSMatthew G. Knepley           break;
81159b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_HEX_3D:
811627fcede3SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
811727fcede3SMatthew G. Knepley             /* Interior vertices stay the same */
811827fcede3SMatthew G. Knepley             newp = vStartNew + (p - vStart);
811927fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
812027fcede3SMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
812127fcede3SMatthew G. Knepley             /* Interior edges add new edges and vertex */
812227fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
812327fcede3SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
812427fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
812527fcede3SMatthew G. Knepley             }
812627fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
812727fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
812827fcede3SMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
812927fcede3SMatthew G. Knepley             /* Hybrid edges stay the same */
813027fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax);
813127fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
813227fcede3SMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
813327fcede3SMatthew G. Knepley             /* Interior faces add new faces, edges, and vertex */
813427fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
813527fcede3SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
813627fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
813727fcede3SMatthew G. Knepley             }
813827fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
813927fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r;
814027fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
814127fcede3SMatthew G. Knepley             }
814227fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
814327fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
814427fcede3SMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
814527fcede3SMatthew G. Knepley             /* Hybrid faces add new faces and edges */
814627fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
814727fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r;
814827fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
814927fcede3SMatthew G. Knepley             }
815027fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax);
815127fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
815227fcede3SMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
815327fcede3SMatthew G. Knepley             /* Interior cells add new cells, faces, edges, and vertex */
815427fcede3SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
815527fcede3SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
815627fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
815727fcede3SMatthew G. Knepley             }
815827fcede3SMatthew G. Knepley             for (r = 0; r < 12; ++r) {
815927fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r;
816027fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
816127fcede3SMatthew G. Knepley             }
816227fcede3SMatthew G. Knepley             for (r = 0; r < 6; ++r) {
816327fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r;
816427fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
816527fcede3SMatthew G. Knepley             }
816627fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart);
816727fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
816827fcede3SMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
816927fcede3SMatthew G. Knepley             /* Hybrid cells add new cells, faces, and edges */
817027fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
817127fcede3SMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
817227fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
817327fcede3SMatthew G. Knepley             }
817427fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
817527fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r;
817627fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
817727fcede3SMatthew G. Knepley             }
817827fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax);
817927fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
818027fcede3SMatthew G. Knepley           }
818127fcede3SMatthew G. Knepley           break;
818275d3a19aSMatthew G. Knepley         default:
818375d3a19aSMatthew G. Knepley           SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
818475d3a19aSMatthew G. Knepley         }
818575d3a19aSMatthew G. Knepley       }
818675d3a19aSMatthew G. Knepley       ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr);
818775d3a19aSMatthew G. Knepley       ierr = ISDestroy(&pointIS);CHKERRQ(ierr);
818875d3a19aSMatthew G. Knepley     }
818975d3a19aSMatthew G. Knepley     ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr);
819075d3a19aSMatthew G. Knepley     ierr = ISDestroy(&valueIS);CHKERRQ(ierr);
819175d3a19aSMatthew G. Knepley     if (0) {
819275d3a19aSMatthew G. Knepley       ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
819375d3a19aSMatthew G. Knepley     }
819475d3a19aSMatthew G. Knepley   }
819575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
819675d3a19aSMatthew G. Knepley }
819775d3a19aSMatthew G. Knepley 
819875d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */
8199509c9b89SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined)
820075d3a19aSMatthew G. Knepley {
820175d3a19aSMatthew G. Knepley   DM             rdm;
820275d3a19aSMatthew G. Knepley   PetscInt      *depthSize;
820375d3a19aSMatthew G. Knepley   PetscInt       dim, depth = 0, d, pStart = 0, pEnd = 0;
820475d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
820575d3a19aSMatthew G. Knepley 
820675d3a19aSMatthew G. Knepley   PetscFunctionBegin;
820775d3a19aSMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr);
820875d3a19aSMatthew G. Knepley   ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr);
8209c73cfb54SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
8210c73cfb54SMatthew G. Knepley   ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr);
821175d3a19aSMatthew G. Knepley   /* Calculate number of new points of each depth */
821275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
82131e573d11SMatthew G. Knepley   if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement");
8214854ce69bSBarry Smith   ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr);
821575d3a19aSMatthew G. Knepley   ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr);
821675d3a19aSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
821775d3a19aSMatthew G. Knepley   /* Step 1: Set chart */
821875d3a19aSMatthew G. Knepley   for (d = 0; d <= depth; ++d) pEnd += depthSize[d];
821975d3a19aSMatthew G. Knepley   ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr);
822075d3a19aSMatthew G. Knepley   /* Step 2: Set cone/support sizes */
822175d3a19aSMatthew G. Knepley   ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
822275d3a19aSMatthew G. Knepley   /* Step 3: Setup refined DM */
822375d3a19aSMatthew G. Knepley   ierr = DMSetUp(rdm);CHKERRQ(ierr);
822475d3a19aSMatthew G. Knepley   /* Step 4: Set cones and supports */
822575d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
822675d3a19aSMatthew G. Knepley   /* Step 5: Stratify */
822775d3a19aSMatthew G. Knepley   ierr = DMPlexStratify(rdm);CHKERRQ(ierr);
82280fadad52SMatthew G. Knepley   /* Step 6: Create pointSF */
822975d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
823090b157c4SStefano Zampini   /* Step 7: Create labels */
823175d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
823290b157c4SStefano Zampini   /* Step 8: Set coordinates */
823390b157c4SStefano Zampini   ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
823475d3a19aSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
823575d3a19aSMatthew G. Knepley 
823675d3a19aSMatthew G. Knepley   *dmRefined = rdm;
823775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
823875d3a19aSMatthew G. Knepley }
823975d3a19aSMatthew G. Knepley 
82402389894bSMatthew G. Knepley /*@
82412389894bSMatthew G. Knepley   DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data
82422389894bSMatthew G. Knepley 
82432389894bSMatthew G. Knepley   Input Parameter:
82442389894bSMatthew G. Knepley . dm - The coarse DM
82452389894bSMatthew G. Knepley 
82462389894bSMatthew G. Knepley   Output Parameter:
82472389894bSMatthew G. Knepley . fpointIS - The IS of all the fine points which exist in the original coarse mesh
82482389894bSMatthew G. Knepley 
82492389894bSMatthew G. Knepley   Level: developer
82502389894bSMatthew G. Knepley 
82512389894bSMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS()
82522389894bSMatthew G. Knepley @*/
82532389894bSMatthew G. Knepley PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS)
82542389894bSMatthew G. Knepley {
82552389894bSMatthew G. Knepley   CellRefiner    cellRefiner;
82562389894bSMatthew G. Knepley   PetscInt      *depthSize, *fpoints;
82572389894bSMatthew G. Knepley   PetscInt       cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
82582389894bSMatthew G. Knepley   PetscInt       depth, pStart, pEnd, p, vStart, vEnd, v;
82592389894bSMatthew G. Knepley   PetscErrorCode ierr;
82602389894bSMatthew G. Knepley 
82612389894bSMatthew G. Knepley   PetscFunctionBegin;
82622389894bSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
82632389894bSMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
82642389894bSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
82652389894bSMatthew G. Knepley   ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr);
8266854ce69bSBarry Smith   ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr);
82672389894bSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
82682389894bSMatthew G. Knepley   if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
82692389894bSMatthew G. Knepley   ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr);
82702389894bSMatthew G. Knepley   for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1;
82712389894bSMatthew G. Knepley   switch (cellRefiner) {
82726c0c04f5SMatthew G. Knepley   case REFINER_SIMPLEX_1D:
82736c0c04f5SMatthew G. Knepley   case REFINER_SIMPLEX_2D:
82746c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_SIMPLEX_2D:
82756c0c04f5SMatthew G. Knepley   case REFINER_HEX_2D:
82766c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_HEX_2D:
82776c0c04f5SMatthew G. Knepley   case REFINER_SIMPLEX_3D:
82786c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_SIMPLEX_3D:
82796c0c04f5SMatthew G. Knepley   case REFINER_HEX_3D:
82806c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_HEX_3D:
82812389894bSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart);
82822389894bSMatthew G. Knepley     break;
82832389894bSMatthew G. Knepley   default:
82842389894bSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", cellRefiner);
82852389894bSMatthew G. Knepley   }
82862389894bSMatthew G. Knepley   ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr);
82872389894bSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
82882389894bSMatthew G. Knepley   PetscFunctionReturn(0);
82892389894bSMatthew G. Knepley }
82902389894bSMatthew G. Knepley 
82910e2b6761SMatthew G. Knepley /*@
82920e2b6761SMatthew G. Knepley   DMPlexSetRefinementUniform - Set the flag for uniform refinement
82930e2b6761SMatthew G. Knepley 
82940e2b6761SMatthew G. Knepley   Input Parameters:
82950e2b6761SMatthew G. Knepley + dm - The DM
82960e2b6761SMatthew G. Knepley - refinementUniform - The flag for uniform refinement
82970e2b6761SMatthew G. Knepley 
82980e2b6761SMatthew G. Knepley   Level: developer
82990e2b6761SMatthew G. Knepley 
83000e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
83010e2b6761SMatthew G. Knepley @*/
830275d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
830375d3a19aSMatthew G. Knepley {
830475d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
830575d3a19aSMatthew G. Knepley 
830675d3a19aSMatthew G. Knepley   PetscFunctionBegin;
830775d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
830875d3a19aSMatthew G. Knepley   mesh->refinementUniform = refinementUniform;
830975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
831075d3a19aSMatthew G. Knepley }
831175d3a19aSMatthew G. Knepley 
83120e2b6761SMatthew G. Knepley /*@
83130e2b6761SMatthew G. Knepley   DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement
83140e2b6761SMatthew G. Knepley 
83150e2b6761SMatthew G. Knepley   Input Parameter:
83160e2b6761SMatthew G. Knepley . dm - The DM
83170e2b6761SMatthew G. Knepley 
83180e2b6761SMatthew G. Knepley   Output Parameter:
83190e2b6761SMatthew G. Knepley . refinementUniform - The flag for uniform refinement
83200e2b6761SMatthew G. Knepley 
83210e2b6761SMatthew G. Knepley   Level: developer
83220e2b6761SMatthew G. Knepley 
83230e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
83240e2b6761SMatthew G. Knepley @*/
832575d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
832675d3a19aSMatthew G. Knepley {
832775d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
832875d3a19aSMatthew G. Knepley 
832975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
833075d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
833175d3a19aSMatthew G. Knepley   PetscValidPointer(refinementUniform,  2);
833275d3a19aSMatthew G. Knepley   *refinementUniform = mesh->refinementUniform;
833375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
833475d3a19aSMatthew G. Knepley }
833575d3a19aSMatthew G. Knepley 
83360e2b6761SMatthew G. Knepley /*@
83370e2b6761SMatthew G. Knepley   DMPlexSetRefinementLimit - Set the maximum cell volume for refinement
83380e2b6761SMatthew G. Knepley 
83390e2b6761SMatthew G. Knepley   Input Parameters:
83400e2b6761SMatthew G. Knepley + dm - The DM
83410e2b6761SMatthew G. Knepley - refinementLimit - The maximum cell volume in the refined mesh
83420e2b6761SMatthew G. Knepley 
83430e2b6761SMatthew G. Knepley   Level: developer
83440e2b6761SMatthew G. Knepley 
83450e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
83460e2b6761SMatthew G. Knepley @*/
834775d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
834875d3a19aSMatthew G. Knepley {
834975d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
835075d3a19aSMatthew G. Knepley 
835175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
835275d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
835375d3a19aSMatthew G. Knepley   mesh->refinementLimit = refinementLimit;
835475d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
835575d3a19aSMatthew G. Knepley }
835675d3a19aSMatthew G. Knepley 
83570e2b6761SMatthew G. Knepley /*@
83580e2b6761SMatthew G. Knepley   DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement
83590e2b6761SMatthew G. Knepley 
83600e2b6761SMatthew G. Knepley   Input Parameter:
83610e2b6761SMatthew G. Knepley . dm - The DM
83620e2b6761SMatthew G. Knepley 
83630e2b6761SMatthew G. Knepley   Output Parameter:
83640e2b6761SMatthew G. Knepley . refinementLimit - The maximum cell volume in the refined mesh
83650e2b6761SMatthew G. Knepley 
83660e2b6761SMatthew G. Knepley   Level: developer
83670e2b6761SMatthew G. Knepley 
83680e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
83690e2b6761SMatthew G. Knepley @*/
837075d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
837175d3a19aSMatthew G. Knepley {
837275d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
837375d3a19aSMatthew G. Knepley 
837475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
837575d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
837675d3a19aSMatthew G. Knepley   PetscValidPointer(refinementLimit,  2);
837775d3a19aSMatthew G. Knepley   /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
837875d3a19aSMatthew G. Knepley   *refinementLimit = mesh->refinementLimit;
837975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
838075d3a19aSMatthew G. Knepley }
838175d3a19aSMatthew G. Knepley 
8382b28003e6SMatthew G. Knepley /*@
8383b28003e6SMatthew G. Knepley   DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement
8384b28003e6SMatthew G. Knepley 
8385b28003e6SMatthew G. Knepley   Input Parameters:
8386b28003e6SMatthew G. Knepley + dm - The DM
8387b28003e6SMatthew G. Knepley - refinementFunc - Function giving the maximum cell volume in the refined mesh
8388b28003e6SMatthew G. Knepley 
8389b28003e6SMatthew G. Knepley   Note: The calling sequence is refinementFunc(coords, limit)
8390b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid
8391b28003e6SMatthew G. Knepley $ limit  - The maximum cell volume for a cell containing this point
8392b28003e6SMatthew G. Knepley 
8393b28003e6SMatthew G. Knepley   Level: developer
8394b28003e6SMatthew G. Knepley 
8395b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
8396b28003e6SMatthew G. Knepley @*/
8397b28003e6SMatthew G. Knepley PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *))
8398b28003e6SMatthew G. Knepley {
8399b28003e6SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
8400b28003e6SMatthew G. Knepley 
8401b28003e6SMatthew G. Knepley   PetscFunctionBegin;
8402b28003e6SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8403b28003e6SMatthew G. Knepley   mesh->refinementFunc = refinementFunc;
8404b28003e6SMatthew G. Knepley   PetscFunctionReturn(0);
8405b28003e6SMatthew G. Knepley }
8406b28003e6SMatthew G. Knepley 
8407b28003e6SMatthew G. Knepley /*@
8408b28003e6SMatthew G. Knepley   DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement
8409b28003e6SMatthew G. Knepley 
8410b28003e6SMatthew G. Knepley   Input Parameter:
8411b28003e6SMatthew G. Knepley . dm - The DM
8412b28003e6SMatthew G. Knepley 
8413b28003e6SMatthew G. Knepley   Output Parameter:
8414b28003e6SMatthew G. Knepley . refinementFunc - Function giving the maximum cell volume in the refined mesh
8415b28003e6SMatthew G. Knepley 
8416b28003e6SMatthew G. Knepley   Note: The calling sequence is refinementFunc(coords, limit)
8417b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid
8418b28003e6SMatthew G. Knepley $ limit  - The maximum cell volume for a cell containing this point
8419b28003e6SMatthew G. Knepley 
8420b28003e6SMatthew G. Knepley   Level: developer
8421b28003e6SMatthew G. Knepley 
8422b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
8423b28003e6SMatthew G. Knepley @*/
8424b28003e6SMatthew G. Knepley PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *))
8425b28003e6SMatthew G. Knepley {
8426b28003e6SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
8427b28003e6SMatthew G. Knepley 
8428b28003e6SMatthew G. Knepley   PetscFunctionBegin;
8429b28003e6SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8430b28003e6SMatthew G. Knepley   PetscValidPointer(refinementFunc,  2);
8431b28003e6SMatthew G. Knepley   *refinementFunc = mesh->refinementFunc;
8432b28003e6SMatthew G. Knepley   PetscFunctionReturn(0);
8433b28003e6SMatthew G. Knepley }
8434b28003e6SMatthew G. Knepley 
8435509c9b89SMatthew G. Knepley PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner)
843675d3a19aSMatthew G. Knepley {
84370f9259d6SMatthew G. Knepley   PetscInt       dim, cStart, cEnd, coneSize, cMax, fMax;
843875d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
843975d3a19aSMatthew G. Knepley 
844075d3a19aSMatthew G. Knepley   PetscFunctionBegin;
8441c73cfb54SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
84423478d7aaSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
84439b1a0e7fSLawrence Mitchell   if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; PetscFunctionReturn(0);}
844475d3a19aSMatthew G. Knepley   ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr);
844589b38ed4SMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, NULL, NULL);CHKERRQ(ierr);
844675d3a19aSMatthew G. Knepley   switch (dim) {
84470314a74cSLawrence Mitchell   case 1:
84480314a74cSLawrence Mitchell     switch (coneSize) {
84490314a74cSLawrence Mitchell     case 2:
84500314a74cSLawrence Mitchell       *cellRefiner = REFINER_SIMPLEX_1D;
84510314a74cSLawrence Mitchell       break;
84520314a74cSLawrence Mitchell     default:
84530314a74cSLawrence Mitchell       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
84540314a74cSLawrence Mitchell     }
84550314a74cSLawrence Mitchell     break;
845675d3a19aSMatthew G. Knepley   case 2:
845775d3a19aSMatthew G. Knepley     switch (coneSize) {
845875d3a19aSMatthew G. Knepley     case 3:
84599b1a0e7fSLawrence Mitchell       if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_2D;
84609b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_SIMPLEX_2D;
846175d3a19aSMatthew G. Knepley       break;
846275d3a19aSMatthew G. Knepley     case 4:
846389b38ed4SMatthew G. Knepley       if (cMax >= 0 && fMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_2D;
84649b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_HEX_2D;
846575d3a19aSMatthew G. Knepley       break;
846675d3a19aSMatthew G. Knepley     default:
846775d3a19aSMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
846875d3a19aSMatthew G. Knepley     }
846975d3a19aSMatthew G. Knepley     break;
8470b5da9499SMatthew G. Knepley   case 3:
8471b5da9499SMatthew G. Knepley     switch (coneSize) {
8472b5da9499SMatthew G. Knepley     case 4:
84739b1a0e7fSLawrence Mitchell       if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D;
84749b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_SIMPLEX_3D;
8475b5da9499SMatthew G. Knepley       break;
84762eabf88fSMatthew G. Knepley     case 6:
84779b1a0e7fSLawrence Mitchell       if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_3D;
84789b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_HEX_3D;
84792eabf88fSMatthew G. Knepley       break;
8480b5da9499SMatthew G. Knepley     default:
8481b5da9499SMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
8482b5da9499SMatthew G. Knepley     }
8483b5da9499SMatthew G. Knepley     break;
848475d3a19aSMatthew G. Knepley   default:
848575d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim);
848675d3a19aSMatthew G. Knepley   }
848775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
848875d3a19aSMatthew G. Knepley }
84890d1cd5e0SMatthew G. Knepley 
84900d1cd5e0SMatthew G. Knepley PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined)
84910d1cd5e0SMatthew G. Knepley {
8492*492b8470SStefano Zampini   PetscBool      isUniform;
84930d1cd5e0SMatthew G. Knepley   PetscErrorCode ierr;
84940d1cd5e0SMatthew G. Knepley 
84950d1cd5e0SMatthew G. Knepley   PetscFunctionBegin;
84960d1cd5e0SMatthew G. Knepley   ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr);
84970d1cd5e0SMatthew G. Knepley   if (isUniform) {
84980d1cd5e0SMatthew G. Knepley     CellRefiner cellRefiner;
8499*492b8470SStefano Zampini     PetscBool   localized;
85000d1cd5e0SMatthew G. Knepley 
8501*492b8470SStefano Zampini     ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr);
85020d1cd5e0SMatthew G. Knepley     ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr);
85030d1cd5e0SMatthew G. Knepley     ierr = DMPlexRefineUniform_Internal(dm, cellRefiner, dmRefined);CHKERRQ(ierr);
85040d1cd5e0SMatthew G. Knepley     ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr);
85050d1cd5e0SMatthew G. Knepley     if (localized) {ierr = DMLocalizeCoordinates(*dmRefined);CHKERRQ(ierr);}
85060d1cd5e0SMatthew G. Knepley   } else {
85070d1cd5e0SMatthew G. Knepley     ierr = DMPlexRefine_Internal(dm, NULL, dmRefined);CHKERRQ(ierr);
85080d1cd5e0SMatthew G. Knepley   }
85090d1cd5e0SMatthew G. Knepley   PetscFunctionReturn(0);
85100d1cd5e0SMatthew G. Knepley }
85110d1cd5e0SMatthew G. Knepley 
85120d1cd5e0SMatthew G. Knepley PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[])
85130d1cd5e0SMatthew G. Knepley {
85140d1cd5e0SMatthew G. Knepley   DM             cdm = dm;
85150d1cd5e0SMatthew G. Knepley   PetscInt       r;
85160d1cd5e0SMatthew G. Knepley   PetscBool      isUniform, localized;
85170d1cd5e0SMatthew G. Knepley   PetscErrorCode ierr;
85180d1cd5e0SMatthew G. Knepley 
85190d1cd5e0SMatthew G. Knepley   PetscFunctionBegin;
85200d1cd5e0SMatthew G. Knepley   ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr);
85210d1cd5e0SMatthew G. Knepley   ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr);
85220d1cd5e0SMatthew G. Knepley   if (isUniform) {
85230d1cd5e0SMatthew G. Knepley     for (r = 0; r < nlevels; ++r) {
85240d1cd5e0SMatthew G. Knepley       CellRefiner cellRefiner;
85250d1cd5e0SMatthew G. Knepley 
85260d1cd5e0SMatthew G. Knepley       ierr = DMPlexGetCellRefiner_Internal(cdm, &cellRefiner);CHKERRQ(ierr);
85270d1cd5e0SMatthew G. Knepley       ierr = DMPlexRefineUniform_Internal(cdm, cellRefiner, &dmRefined[r]);CHKERRQ(ierr);
85280d1cd5e0SMatthew G. Knepley       ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr);
85290d1cd5e0SMatthew G. Knepley       if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);}
85300d1cd5e0SMatthew G. Knepley       ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr);
85310d1cd5e0SMatthew G. Knepley       ierr = DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);CHKERRQ(ierr);
85320d1cd5e0SMatthew G. Knepley       cdm  = dmRefined[r];
85330d1cd5e0SMatthew G. Knepley     }
85340d1cd5e0SMatthew G. Knepley   } else {
85350d1cd5e0SMatthew G. Knepley     for (r = 0; r < nlevels; ++r) {
85360d1cd5e0SMatthew G. Knepley       ierr = DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);CHKERRQ(ierr);
85370d1cd5e0SMatthew G. Knepley       ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr);
85380d1cd5e0SMatthew G. Knepley       if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);}
85390d1cd5e0SMatthew G. Knepley       ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr);
85400d1cd5e0SMatthew G. Knepley       cdm  = dmRefined[r];
85410d1cd5e0SMatthew G. Knepley     }
85420d1cd5e0SMatthew G. Knepley   }
85430d1cd5e0SMatthew G. Knepley   PetscFunctionReturn(0);
85440d1cd5e0SMatthew G. Knepley }
8545