xref: /petsc/src/dm/impls/plex/plexrefine.c (revision 451a39c7b36d83a9fceb521f9246cec2ccdca23b)
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;
182175d3a19aSMatthew G. Knepley       orntNew[2] = 0;
182275d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
182375d3a19aSMatthew G. Knepley       orntNew[3] = -2;
182475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
182575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
182675d3a19aSMatthew G. Knepley #if 1
182775d3a19aSMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew);
182875d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
182975d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
183075d3a19aSMatthew G. Knepley       }
183175d3a19aSMatthew G. Knepley #endif
183275d3a19aSMatthew G. Knepley       /* C quad */
183375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
183475d3a19aSMatthew G. Knepley       orntNew[0] = -2;
183575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
183675d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
183775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
183875d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
183975d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
184075d3a19aSMatthew G. Knepley       orntNew[3] = 0;
184175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
184275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
184375d3a19aSMatthew G. Knepley #if 1
184475d3a19aSMatthew G. Knepley       if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew);
184575d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
184675d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
184775d3a19aSMatthew G. Knepley       }
184875d3a19aSMatthew G. Knepley #endif
184975d3a19aSMatthew G. Knepley       /* D quad */
185075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
185175d3a19aSMatthew G. Knepley       orntNew[0] = 0;
185275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
185375d3a19aSMatthew G. Knepley       orntNew[1] = -2;
185475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
185575d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
185675d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
185775d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
185875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
185975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
186075d3a19aSMatthew G. Knepley #if 1
186175d3a19aSMatthew G. Knepley       if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew);
186275d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
186375d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
186475d3a19aSMatthew G. Knepley       }
186575d3a19aSMatthew G. Knepley #endif
186675d3a19aSMatthew G. Knepley     }
186775d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
186875d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1869854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
187075d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
187175d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
187275d3a19aSMatthew G. Knepley 
187375d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
187475d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1875455d6cd4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
187675d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
187775d3a19aSMatthew G. Knepley 
187875d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
187975d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
188075d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
188175d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
188275d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
188375d3a19aSMatthew G. Knepley #if 1
188475d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
188575d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
188675d3a19aSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
188775d3a19aSMatthew G. Knepley         }
188875d3a19aSMatthew G. Knepley #endif
188975d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
189075d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
189175d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
189275d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
189375d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1894455d6cd4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
189575d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
189675d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
189775d3a19aSMatthew G. Knepley           }
1898455d6cd4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
189975d3a19aSMatthew G. Knepley         }
190075d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
190175d3a19aSMatthew G. Knepley #if 1
190275d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
190375d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
190475d3a19aSMatthew G. Knepley           if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
190575d3a19aSMatthew G. Knepley         }
190675d3a19aSMatthew G. Knepley #endif
190775d3a19aSMatthew G. Knepley       }
190875d3a19aSMatthew G. Knepley     }
190975d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
191075d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
191175d3a19aSMatthew G. Knepley       const PetscInt *cone;
191275d3a19aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
191375d3a19aSMatthew G. Knepley 
191475d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
191575d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
191675d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
191775d3a19aSMatthew G. Knepley 
191875d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
191975d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd    - fStart) + (c - cStart);
192075d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
192175d3a19aSMatthew G. Knepley #if 1
192275d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
192375d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
192475d3a19aSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
192575d3a19aSMatthew G. Knepley         }
192675d3a19aSMatthew G. Knepley #endif
192775d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
192875d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
192975d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
193075d3a19aSMatthew G. Knepley #if 1
193175d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
193275d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
193375d3a19aSMatthew G. Knepley           if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
193475d3a19aSMatthew G. Knepley         }
193575d3a19aSMatthew G. Knepley #endif
193675d3a19aSMatthew G. Knepley       }
193775d3a19aSMatthew G. Knepley     }
193875d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
193975d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
194075d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
194175d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
194275d3a19aSMatthew G. Knepley       PetscInt        size, s;
194375d3a19aSMatthew G. Knepley 
194475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
194575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
194675d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
194775d3a19aSMatthew G. Knepley         PetscInt r = 0;
194875d3a19aSMatthew G. Knepley 
194975d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
195075d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
195175d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
195275d3a19aSMatthew G. Knepley       }
195375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
195475d3a19aSMatthew G. Knepley #if 1
195575d3a19aSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
195675d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
195775d3a19aSMatthew G. Knepley         if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
195875d3a19aSMatthew G. Knepley       }
195975d3a19aSMatthew G. Knepley #endif
196075d3a19aSMatthew G. Knepley     }
196175d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
196275d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
196375d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
196475d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
196575d3a19aSMatthew G. Knepley       PetscInt        size, s;
196675d3a19aSMatthew G. Knepley 
196775d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
196875d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
196975d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
197075d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
197175d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
197275d3a19aSMatthew G. Knepley         PetscInt r = 0;
197375d3a19aSMatthew G. Knepley 
197475d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
197575d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
197675d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
197775d3a19aSMatthew G. Knepley         else if (cone[3] == f) r = 3;
197875d3a19aSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r;
197975d3a19aSMatthew G. Knepley       }
198075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
198175d3a19aSMatthew G. Knepley #if 1
198275d3a19aSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
198375d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
198475d3a19aSMatthew G. Knepley         if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
198575d3a19aSMatthew G. Knepley       }
198675d3a19aSMatthew G. Knepley #endif
198775d3a19aSMatthew G. Knepley     }
198875d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
198975d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
199075d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
199175d3a19aSMatthew G. Knepley       PetscInt       supportNew[4];
199275d3a19aSMatthew G. Knepley 
199375d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
199475d3a19aSMatthew G. Knepley         supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
199575d3a19aSMatthew G. Knepley       }
199675d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
199775d3a19aSMatthew G. Knepley     }
1998da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
199975d3a19aSMatthew G. Knepley     break;
20009b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
200175d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
200275d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
200375d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
200475d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
2005149f48fdSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr);
200675d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
200775d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
200875d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
200975d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
201075d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
201175d3a19aSMatthew G. Knepley 
201275d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
201375d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
201475d3a19aSMatthew G. Knepley       /* A triangle */
201575d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
201675d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
201775d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
201875d3a19aSMatthew G. Knepley       orntNew[1] = -2;
201975d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
202075d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
202175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
202275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
202375d3a19aSMatthew G. Knepley #if 1
2024149f48fdSMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+0, cStartNew, cMaxNew);
202575d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2026149f48fdSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
202775d3a19aSMatthew G. Knepley       }
202875d3a19aSMatthew G. Knepley #endif
202975d3a19aSMatthew G. Knepley       /* B triangle */
203075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
203175d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
203275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
203375d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
203475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
203575d3a19aSMatthew G. Knepley       orntNew[2] = -2;
203675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
203775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
203875d3a19aSMatthew G. Knepley #if 1
2039a97b51b8SMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+1, cStartNew, cMaxNew);
204075d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2041a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
204275d3a19aSMatthew G. Knepley       }
204375d3a19aSMatthew G. Knepley #endif
204475d3a19aSMatthew G. Knepley       /* C triangle */
204575d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
204675d3a19aSMatthew G. Knepley       orntNew[0] = -2;
204775d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
204875d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
204975d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
205075d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
205175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
205275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
205375d3a19aSMatthew G. Knepley #if 1
2054a97b51b8SMatthew G. Knepley       if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+2, cStartNew, cMaxNew);
205575d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2056a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
205775d3a19aSMatthew G. Knepley       }
205875d3a19aSMatthew G. Knepley #endif
205975d3a19aSMatthew G. Knepley       /* D triangle */
206075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
206175d3a19aSMatthew G. Knepley       orntNew[0] = 0;
206275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
206375d3a19aSMatthew G. Knepley       orntNew[1] = 0;
206475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
206575d3a19aSMatthew G. Knepley       orntNew[2] = 0;
206675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
206775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
206875d3a19aSMatthew G. Knepley #if 1
2069a97b51b8SMatthew G. Knepley       if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+3, cStartNew, cMaxNew);
207075d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2071a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
207275d3a19aSMatthew G. Knepley       }
207375d3a19aSMatthew G. Knepley #endif
207475d3a19aSMatthew G. Knepley     }
207575d3a19aSMatthew G. Knepley     /*
207675d3a19aSMatthew G. Knepley      2----3----3
207775d3a19aSMatthew G. Knepley      |         |
207875d3a19aSMatthew G. Knepley      |    B    |
207975d3a19aSMatthew G. Knepley      |         |
208075d3a19aSMatthew G. Knepley      0----4--- 1
208175d3a19aSMatthew G. Knepley      |         |
208275d3a19aSMatthew G. Knepley      |    A    |
208375d3a19aSMatthew G. Knepley      |         |
208475d3a19aSMatthew G. Knepley      0----2----1
208575d3a19aSMatthew G. Knepley      */
208675d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
208775d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
208875d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
208975d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
2090ea00e70eSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4], r;
209175d3a19aSMatthew G. Knepley 
209275d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
209375d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2094ea00e70eSMatthew G. Knepley       r    = (ornt[0] < 0 ? 1 : 0);
209575d3a19aSMatthew G. Knepley       /* A quad */
2096ea00e70eSMatthew G. Knepley       coneNew[0]   = fStartNew + (cone[0] - fStart)*2 + r;
209775d3a19aSMatthew G. Knepley       orntNew[0]   = ornt[0];
2098ea00e70eSMatthew G. Knepley       coneNew[1]   = fStartNew + (cone[1] - fStart)*2 + r;
209975d3a19aSMatthew G. Knepley       orntNew[1]   = ornt[1];
2100ea00e70eSMatthew G. Knepley       coneNew[2+r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax);
2101ea00e70eSMatthew G. Knepley       orntNew[2+r] = 0;
2102ea00e70eSMatthew G. Knepley       coneNew[3-r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
2103ea00e70eSMatthew G. Knepley       orntNew[3-r] = 0;
210475d3a19aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
210575d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
210675d3a19aSMatthew G. Knepley #if 1
210775d3a19aSMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew);
210875d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
210975d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
211075d3a19aSMatthew G. Knepley       }
211175d3a19aSMatthew G. Knepley #endif
211275d3a19aSMatthew G. Knepley       /* B quad */
2113ea00e70eSMatthew G. Knepley       coneNew[0]   = fStartNew + (cone[0] - fStart)*2 + 1-r;
211475d3a19aSMatthew G. Knepley       orntNew[0]   = ornt[0];
2115ea00e70eSMatthew G. Knepley       coneNew[1]   = fStartNew + (cone[1] - fStart)*2 + 1-r;
211675d3a19aSMatthew G. Knepley       orntNew[1]   = ornt[1];
2117ea00e70eSMatthew G. Knepley       coneNew[2+r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
2118ea00e70eSMatthew G. Knepley       orntNew[2+r] = 0;
2119ea00e70eSMatthew G. Knepley       coneNew[3-r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax);
2120ea00e70eSMatthew G. Knepley       orntNew[3-r] = 0;
212175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
212275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
212375d3a19aSMatthew G. Knepley #if 1
212475d3a19aSMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew);
212575d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
212675d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
212775d3a19aSMatthew G. Knepley       }
212875d3a19aSMatthew G. Knepley #endif
212975d3a19aSMatthew G. Knepley     }
213075d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
213175d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2132854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
213375d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
213475d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
213575d3a19aSMatthew G. Knepley 
213675d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
213775d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
2138297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
213975d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
214075d3a19aSMatthew G. Knepley 
214175d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
214275d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
214375d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
214475d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
214575d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
214675d3a19aSMatthew G. Knepley #if 1
214775d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
214875d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
214975d3a19aSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
215075d3a19aSMatthew G. Knepley         }
215175d3a19aSMatthew G. Knepley #endif
215275d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
215375d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
215475d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
215575d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
215675d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2157297d2bf4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2158ea00e70eSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == f) break;
2159ea00e70eSMatthew G. Knepley           if (support[s] >= cMax) {
2160ea00e70eSMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r);
2161ea00e70eSMatthew G. Knepley           } else {
2162297d2bf4SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
216375d3a19aSMatthew G. Knepley           }
216475d3a19aSMatthew G. Knepley         }
216575d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
216675d3a19aSMatthew G. Knepley #if 1
216775d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
216875d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
216975d3a19aSMatthew G. Knepley           if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
217075d3a19aSMatthew G. Knepley         }
217175d3a19aSMatthew G. Knepley #endif
217275d3a19aSMatthew G. Knepley       }
217375d3a19aSMatthew G. Knepley     }
217475d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
217575d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
217675d3a19aSMatthew G. Knepley       const PetscInt *cone;
217775d3a19aSMatthew G. Knepley 
217875d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
217975d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
218075d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
218175d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
218275d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
218375d3a19aSMatthew G. Knepley 
218475d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
218575d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
218675d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
218775d3a19aSMatthew G. Knepley #if 1
218875d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
218975d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
219075d3a19aSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
219175d3a19aSMatthew G. Knepley         }
219275d3a19aSMatthew G. Knepley #endif
219375d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
219475d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
219575d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
219675d3a19aSMatthew G. Knepley #if 1
219775d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
219875d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
219975d3a19aSMatthew G. Knepley           if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
220075d3a19aSMatthew G. Knepley         }
220175d3a19aSMatthew G. Knepley #endif
220275d3a19aSMatthew G. Knepley       }
220375d3a19aSMatthew G. Knepley     }
220475d3a19aSMatthew G. Knepley     /* Interior hybrid faces have 2 vertices and the same cells */
220575d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
220675d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
2207ea00e70eSMatthew G. Knepley       const PetscInt *cone, *ornt;
220875d3a19aSMatthew G. Knepley       const PetscInt *support;
220975d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
221075d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
221175d3a19aSMatthew G. Knepley       PetscInt        size, s, r;
221275d3a19aSMatthew G. Knepley 
221375d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
221475d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
221575d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
221675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
221775d3a19aSMatthew G. Knepley #if 1
221875d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
221975d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
222075d3a19aSMatthew G. Knepley         if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
222175d3a19aSMatthew G. Knepley       }
222275d3a19aSMatthew G. Knepley #endif
222375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
222475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
222575d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
222675d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2227ea00e70eSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
222875d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r) {
222975d3a19aSMatthew G. Knepley           if (cone[r+2] == f) break;
223075d3a19aSMatthew G. Knepley         }
2231ea00e70eSMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r);
223275d3a19aSMatthew G. Knepley       }
223375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
223475d3a19aSMatthew G. Knepley #if 1
223575d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
223675d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
223775d3a19aSMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
223875d3a19aSMatthew G. Knepley       }
223975d3a19aSMatthew G. Knepley #endif
224075d3a19aSMatthew G. Knepley     }
224175d3a19aSMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
224275d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
224375d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
224475d3a19aSMatthew G. Knepley       const PetscInt *cone;
224575d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
224675d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
224775d3a19aSMatthew G. Knepley 
224875d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
224975d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
225075d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
225175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
225275d3a19aSMatthew G. Knepley #if 1
225375d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
225475d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
225575d3a19aSMatthew G. Knepley         if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
225675d3a19aSMatthew G. Knepley       }
225775d3a19aSMatthew G. Knepley #endif
225875d3a19aSMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
225975d3a19aSMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
226075d3a19aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
226175d3a19aSMatthew G. Knepley #if 1
226275d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
226375d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
226475d3a19aSMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
226575d3a19aSMatthew G. Knepley       }
226675d3a19aSMatthew G. Knepley #endif
226775d3a19aSMatthew G. Knepley     }
226875d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
226975d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
227075d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
227175d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
227275d3a19aSMatthew G. Knepley       PetscInt        size, s;
227375d3a19aSMatthew G. Knepley 
227475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
227575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
227675d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
227775d3a19aSMatthew G. Knepley         if (support[s] >= fMax) {
227875d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax);
227975d3a19aSMatthew G. Knepley         } else {
228075d3a19aSMatthew G. Knepley           PetscInt r = 0;
228175d3a19aSMatthew G. Knepley 
228275d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
228375d3a19aSMatthew G. Knepley           if (cone[1] == v) r = 1;
228475d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
228575d3a19aSMatthew G. Knepley         }
228675d3a19aSMatthew G. Knepley       }
228775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
228875d3a19aSMatthew G. Knepley #if 1
228975d3a19aSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
229075d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
229175d3a19aSMatthew G. Knepley         if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
229275d3a19aSMatthew G. Knepley       }
229375d3a19aSMatthew G. Knepley #endif
229475d3a19aSMatthew G. Knepley     }
229575d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
229675d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
229775d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
229875d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
229975d3a19aSMatthew G. Knepley       PetscInt        size, newSize = 2, s;
230075d3a19aSMatthew G. Knepley 
230175d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
230275d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
230375d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
230475d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
230575d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
230675d3a19aSMatthew G. Knepley         PetscInt r = 0;
230775d3a19aSMatthew G. Knepley 
230875d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
230975d3a19aSMatthew G. Knepley         if (support[s] >= cMax) {
231075d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax);
231175d3a19aSMatthew G. Knepley 
231275d3a19aSMatthew G. Knepley           newSize += 1;
231375d3a19aSMatthew G. Knepley         } else {
231475d3a19aSMatthew G. Knepley           if      (cone[1] == f) r = 1;
231575d3a19aSMatthew G. Knepley           else if (cone[2] == f) r = 2;
231675d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
231775d3a19aSMatthew G. Knepley           supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r;
231875d3a19aSMatthew G. Knepley 
231975d3a19aSMatthew G. Knepley           newSize += 2;
232075d3a19aSMatthew G. Knepley         }
232175d3a19aSMatthew G. Knepley       }
232275d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
232375d3a19aSMatthew G. Knepley #if 1
232475d3a19aSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
232575d3a19aSMatthew G. Knepley       for (p = 0; p < newSize; ++p) {
232675d3a19aSMatthew G. Knepley         if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
232775d3a19aSMatthew G. Knepley       }
232875d3a19aSMatthew G. Knepley #endif
232975d3a19aSMatthew G. Knepley     }
233075d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
233175d3a19aSMatthew G. Knepley     break;
23329b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
2333a97b51b8SMatthew G. Knepley     /* Hybrid Hex 2D */
2334a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
2335a97b51b8SMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
2336a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
2337a97b51b8SMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
2338a97b51b8SMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr);
2339a97b51b8SMatthew G. Knepley     /* Interior cells have 4 faces */
2340a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
2341a97b51b8SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
2342a97b51b8SMatthew G. Knepley       const PetscInt *cone, *ornt;
2343a97b51b8SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
2344a97b51b8SMatthew G. Knepley 
2345a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2346a97b51b8SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2347a97b51b8SMatthew G. Knepley       /* A quad */
2348a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2349a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2350a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 0;
2351a97b51b8SMatthew G. Knepley       orntNew[1] = 0;
2352a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 3;
2353a97b51b8SMatthew G. Knepley       orntNew[2] = -2;
2354a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
2355a97b51b8SMatthew G. Knepley       orntNew[3] = ornt[3];
2356a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2357a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2358a97b51b8SMatthew G. Knepley #if 1
2359a97b51b8SMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+0, cStartNew, cMaxNew);
2360a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2361a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
2362a97b51b8SMatthew G. Knepley       }
2363a97b51b8SMatthew G. Knepley #endif
2364a97b51b8SMatthew G. Knepley       /* B quad */
2365a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2366a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2367a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2368a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2369a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 1;
2370a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
2371a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 0;
2372a97b51b8SMatthew G. Knepley       orntNew[3] = -2;
2373a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2374a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2375a97b51b8SMatthew G. Knepley #if 1
2376a97b51b8SMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+1, cStartNew, cMaxNew);
2377a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2378a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
2379a97b51b8SMatthew G. Knepley       }
2380a97b51b8SMatthew G. Knepley #endif
2381a97b51b8SMatthew G. Knepley       /* C quad */
2382a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 1;
2383a97b51b8SMatthew G. Knepley       orntNew[0] = -2;
2384a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2385a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2386a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
2387a97b51b8SMatthew G. Knepley       orntNew[2] = ornt[2];
2388a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 2;
2389a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
2390a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2391a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2392a97b51b8SMatthew G. Knepley #if 1
2393a97b51b8SMatthew G. Knepley       if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+2, cStartNew, cMaxNew);
2394a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2395a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
2396a97b51b8SMatthew G. Knepley       }
2397a97b51b8SMatthew G. Knepley #endif
2398a97b51b8SMatthew G. Knepley       /* D quad */
2399a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 3;
2400a97b51b8SMatthew G. Knepley       orntNew[0] = 0;
2401a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 2;
2402a97b51b8SMatthew G. Knepley       orntNew[1] = -2;
2403a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
2404a97b51b8SMatthew G. Knepley       orntNew[2] = ornt[2];
2405a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
2406a97b51b8SMatthew G. Knepley       orntNew[3] = ornt[3];
2407a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2408a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2409a97b51b8SMatthew G. Knepley #if 1
2410a97b51b8SMatthew G. Knepley       if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+3, cStartNew, cMaxNew);
2411a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2412a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
2413a97b51b8SMatthew G. Knepley       }
2414a97b51b8SMatthew G. Knepley #endif
2415a97b51b8SMatthew G. Knepley     }
2416a97b51b8SMatthew G. Knepley     /*
2417a97b51b8SMatthew G. Knepley      2----3----3
2418a97b51b8SMatthew G. Knepley      |         |
2419a97b51b8SMatthew G. Knepley      |    B    |
2420a97b51b8SMatthew G. Knepley      |         |
2421a97b51b8SMatthew G. Knepley      0----4--- 1
2422a97b51b8SMatthew G. Knepley      |         |
2423a97b51b8SMatthew G. Knepley      |    A    |
2424a97b51b8SMatthew G. Knepley      |         |
2425a97b51b8SMatthew G. Knepley      0----2----1
2426a97b51b8SMatthew G. Knepley      */
2427a97b51b8SMatthew G. Knepley     /* Hybrid cells have 4 faces */
2428a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
2429a97b51b8SMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
2430a97b51b8SMatthew G. Knepley       const PetscInt *cone, *ornt;
2431a97b51b8SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
2432a97b51b8SMatthew G. Knepley 
2433a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2434a97b51b8SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2435a97b51b8SMatthew G. Knepley       /* A quad */
2436a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2437a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2438a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2439a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2440a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax);
2441a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
2442a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (fEnd    - fMax) + (c - cMax);
2443a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
2444a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2445a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2446a97b51b8SMatthew G. Knepley #if 1
2447a97b51b8SMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew);
2448a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2449a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
2450a97b51b8SMatthew G. Knepley       }
2451a97b51b8SMatthew G. Knepley #endif
2452a97b51b8SMatthew G. Knepley       /* B quad */
2453a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2454a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2455a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2456a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2457a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (fEnd    - fMax) + (c - cMax);
2458a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
2459a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax);
2460a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
2461a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2462a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2463a97b51b8SMatthew G. Knepley #if 1
2464a97b51b8SMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew);
2465a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2466a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
2467a97b51b8SMatthew G. Knepley       }
2468a97b51b8SMatthew G. Knepley #endif
2469a97b51b8SMatthew G. Knepley     }
2470a97b51b8SMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
2471a97b51b8SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2472854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
2473a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
2474a97b51b8SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
2475a97b51b8SMatthew G. Knepley 
2476a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
2477a97b51b8SMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
2478a97b51b8SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
2479a97b51b8SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
2480a97b51b8SMatthew G. Knepley 
2481a97b51b8SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2482a97b51b8SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
2483a97b51b8SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
2484a97b51b8SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
2485a97b51b8SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2486a97b51b8SMatthew G. Knepley #if 1
2487a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2488a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2489a97b51b8SMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
2490a97b51b8SMatthew G. Knepley         }
2491a97b51b8SMatthew G. Knepley #endif
2492a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2493a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2494a97b51b8SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2495a97b51b8SMatthew G. Knepley           if (support[s] >= cMax) {
2496a97b51b8SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
2497a97b51b8SMatthew G. Knepley           } else {
2498a97b51b8SMatthew G. Knepley             ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2499a97b51b8SMatthew G. Knepley             ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2500a97b51b8SMatthew G. Knepley             ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2501a97b51b8SMatthew G. Knepley             for (c = 0; c < coneSize; ++c) {
2502a97b51b8SMatthew G. Knepley               if (cone[c] == f) break;
2503a97b51b8SMatthew G. Knepley             }
2504a97b51b8SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
2505a97b51b8SMatthew G. Knepley           }
2506a97b51b8SMatthew G. Knepley         }
2507a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2508a97b51b8SMatthew G. Knepley #if 1
2509a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2510a97b51b8SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2511a97b51b8SMatthew G. Knepley           if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
2512a97b51b8SMatthew G. Knepley         }
2513a97b51b8SMatthew G. Knepley #endif
2514a97b51b8SMatthew G. Knepley       }
2515a97b51b8SMatthew G. Knepley     }
2516a97b51b8SMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
2517a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
2518a97b51b8SMatthew G. Knepley       const PetscInt *cone;
2519a97b51b8SMatthew G. Knepley 
2520a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2521a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2522a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
2523a97b51b8SMatthew G. Knepley         PetscInt       coneNew[2], supportNew[2];
2524a97b51b8SMatthew G. Knepley 
2525a97b51b8SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2526a97b51b8SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fMax    - fStart) + (c - cStart);
2527a97b51b8SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2528a97b51b8SMatthew G. Knepley #if 1
2529a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2530a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2531a97b51b8SMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
2532a97b51b8SMatthew G. Knepley         }
2533a97b51b8SMatthew G. Knepley #endif
2534a97b51b8SMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
2535a97b51b8SMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
2536a97b51b8SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2537a97b51b8SMatthew G. Knepley #if 1
2538a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2539a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2540a97b51b8SMatthew G. Knepley           if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
2541a97b51b8SMatthew G. Knepley         }
2542a97b51b8SMatthew G. Knepley #endif
2543a97b51b8SMatthew G. Knepley       }
2544a97b51b8SMatthew G. Knepley     }
2545a97b51b8SMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
2546a97b51b8SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
2547a97b51b8SMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
2548a97b51b8SMatthew G. Knepley       const PetscInt *cone, *support;
2549a97b51b8SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
2550a97b51b8SMatthew G. Knepley       PetscInt        size, s, r;
2551a97b51b8SMatthew G. Knepley 
2552a97b51b8SMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2553a97b51b8SMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
2554a97b51b8SMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
2555a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2556a97b51b8SMatthew G. Knepley #if 1
2557a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2558a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2559a97b51b8SMatthew G. Knepley         if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
2560a97b51b8SMatthew G. Knepley       }
2561a97b51b8SMatthew G. Knepley #endif
2562a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
2563a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2564a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2565a97b51b8SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2566a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r) {
2567a97b51b8SMatthew G. Knepley           if (cone[r+2] == f) break;
2568a97b51b8SMatthew G. Knepley         }
2569a97b51b8SMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
2570a97b51b8SMatthew G. Knepley       }
2571a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2572a97b51b8SMatthew G. Knepley #if 1
2573a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2574a97b51b8SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2575a97b51b8SMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
2576a97b51b8SMatthew G. Knepley       }
2577a97b51b8SMatthew G. Knepley #endif
2578a97b51b8SMatthew G. Knepley     }
2579a97b51b8SMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
2580a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
2581a97b51b8SMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
2582a97b51b8SMatthew G. Knepley       const PetscInt *cone;
2583a97b51b8SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
2584a97b51b8SMatthew G. Knepley 
2585a97b51b8SMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2586a97b51b8SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
2587a97b51b8SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
2588a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2589a97b51b8SMatthew G. Knepley #if 1
2590a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2591a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2592a97b51b8SMatthew G. Knepley         if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
2593a97b51b8SMatthew G. Knepley       }
2594a97b51b8SMatthew G. Knepley #endif
2595a97b51b8SMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
2596a97b51b8SMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
2597a97b51b8SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2598a97b51b8SMatthew G. Knepley #if 1
2599a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2600a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2601a97b51b8SMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
2602a97b51b8SMatthew G. Knepley       }
2603a97b51b8SMatthew G. Knepley #endif
2604a97b51b8SMatthew G. Knepley     }
2605a97b51b8SMatthew G. Knepley     /* Old vertices have identical supports */
2606a97b51b8SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
2607a97b51b8SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
2608a97b51b8SMatthew G. Knepley       const PetscInt *support, *cone;
2609a97b51b8SMatthew G. Knepley       PetscInt        size, s;
2610a97b51b8SMatthew G. Knepley 
2611a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
2612a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
2613a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2614a97b51b8SMatthew G. Knepley         if (support[s] >= fMax) {
2615a97b51b8SMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax);
2616a97b51b8SMatthew G. Knepley         } else {
2617a97b51b8SMatthew G. Knepley           PetscInt r = 0;
2618a97b51b8SMatthew G. Knepley 
2619a97b51b8SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2620a97b51b8SMatthew G. Knepley           if (cone[1] == v) r = 1;
2621a97b51b8SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
2622a97b51b8SMatthew G. Knepley         }
2623a97b51b8SMatthew G. Knepley       }
2624a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2625a97b51b8SMatthew G. Knepley #if 1
2626a97b51b8SMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
2627a97b51b8SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2628a97b51b8SMatthew G. Knepley         if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
2629a97b51b8SMatthew G. Knepley       }
2630a97b51b8SMatthew G. Knepley #endif
2631a97b51b8SMatthew G. Knepley     }
2632a97b51b8SMatthew G. Knepley     /* Face vertices have 2 + cells supports */
2633a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
2634a97b51b8SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
2635a97b51b8SMatthew G. Knepley       const PetscInt *cone, *support;
2636a97b51b8SMatthew G. Knepley       PetscInt        size, s;
2637a97b51b8SMatthew G. Knepley 
2638a97b51b8SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
2639a97b51b8SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2640a97b51b8SMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
2641a97b51b8SMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
2642a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2643a97b51b8SMatthew G. Knepley         PetscInt r = 0;
2644a97b51b8SMatthew G. Knepley 
2645a97b51b8SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2646a97b51b8SMatthew G. Knepley         if (support[s] >= cMax) {
2647a97b51b8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax);
2648a97b51b8SMatthew G. Knepley         } else {
2649a97b51b8SMatthew G. Knepley           if      (cone[1] == f) r = 1;
2650a97b51b8SMatthew G. Knepley           else if (cone[2] == f) r = 2;
2651a97b51b8SMatthew G. Knepley           else if (cone[3] == f) r = 3;
2652a97b51b8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r;
2653a97b51b8SMatthew G. Knepley         }
2654a97b51b8SMatthew G. Knepley       }
2655a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2656a97b51b8SMatthew G. Knepley #if 1
2657a97b51b8SMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
2658a97b51b8SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
2659a97b51b8SMatthew G. Knepley         if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
2660a97b51b8SMatthew G. Knepley       }
2661a97b51b8SMatthew G. Knepley #endif
2662a97b51b8SMatthew G. Knepley     }
2663a97b51b8SMatthew G. Knepley     /* Cell vertices have 4 supports */
2664a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
2665a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
2666a97b51b8SMatthew G. Knepley       PetscInt       supportNew[4];
2667a97b51b8SMatthew G. Knepley 
2668a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2669a97b51b8SMatthew G. Knepley         supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
2670a97b51b8SMatthew G. Knepley       }
2671a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2672a97b51b8SMatthew G. Knepley     }
2673a97b51b8SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
2674a97b51b8SMatthew G. Knepley     break;
26759b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
2676b5da9499SMatthew G. Knepley     /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
2677b5da9499SMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
2678b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2679b5da9499SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
2680b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
2681b5da9499SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
2682b5da9499SMatthew G. Knepley 
2683b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2684b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2685b5da9499SMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
2686518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
2687b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2688518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
2689b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2690518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
2691b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2692b5da9499SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
2693b5da9499SMatthew G. Knepley       orntNew[3] = 0;
2694b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2695b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2696b5da9499SMatthew G. Knepley #if 1
2697b5da9499SMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew);
2698b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2699b5da9499SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
2700b5da9499SMatthew G. Knepley       }
2701b5da9499SMatthew G. Knepley #endif
2702b5da9499SMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
2703518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
2704b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2705518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
2706b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2707b5da9499SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
2708b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2709518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
2710b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2711b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2712b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2713b5da9499SMatthew G. Knepley #if 1
2714b5da9499SMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew);
2715b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2716b5da9499SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
2717b5da9499SMatthew G. Knepley       }
2718b5da9499SMatthew G. Knepley #endif
2719b5da9499SMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
2720518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
2721b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2722b5da9499SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
2723b5da9499SMatthew G. Knepley       orntNew[1] = 0;
2724518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
2725b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2726518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
2727b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2728b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2729b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2730b5da9499SMatthew G. Knepley #if 1
2731b5da9499SMatthew G. Knepley       if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew);
2732b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2733b5da9499SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
2734b5da9499SMatthew G. Knepley       }
2735b5da9499SMatthew G. Knepley #endif
2736b5da9499SMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
2737b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
2738b5da9499SMatthew G. Knepley       orntNew[0] = 0;
2739518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
2740b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2741518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
2742b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2743518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
2744b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2745b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2746b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2747b5da9499SMatthew G. Knepley #if 1
2748b5da9499SMatthew G. Knepley       if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew);
2749b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2750b5da9499SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
2751b5da9499SMatthew G. Knepley       }
2752b5da9499SMatthew G. Knepley #endif
27533fe31fa2SToby Isaac       /* A' tetrahedron: {c, d, a, f} */
2754b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
2755b5da9499SMatthew G. Knepley       orntNew[0] = -3;
2756fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
2757e5337592SStefano Zampini       orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0);
2758fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
2759fac4ab25SMatthew G. Knepley       orntNew[2] = 0;
2760fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
2761fac4ab25SMatthew G. Knepley       orntNew[3] = 2;
2762b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
2763b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
2764b5da9499SMatthew G. Knepley #if 1
2765b5da9499SMatthew G. Knepley       if ((newp+4 < cStartNew) || (newp+4 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+4, cStartNew, cEndNew);
2766b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2767b5da9499SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
2768b5da9499SMatthew G. Knepley       }
2769b5da9499SMatthew G. Knepley #endif
2770b5da9499SMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
2771b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
27723fe31fa2SToby Isaac       orntNew[0] = -2;
27733fe31fa2SToby Isaac       coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3;
2774e5337592SStefano Zampini       orntNew[1] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 1)+1) : GetTriMidEdge_Static(ornt[3], 1);
27753fe31fa2SToby Isaac       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
2776b5da9499SMatthew G. Knepley       orntNew[2] = 0;
27773fe31fa2SToby Isaac       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
27783fe31fa2SToby Isaac       orntNew[3] = 0;
2779b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
2780b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
2781b5da9499SMatthew G. Knepley #if 1
2782b5da9499SMatthew G. Knepley       if ((newp+5 < cStartNew) || (newp+5 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+5, cStartNew, cEndNew);
2783b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2784b5da9499SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
2785b5da9499SMatthew G. Knepley       }
2786b5da9499SMatthew G. Knepley #endif
27873fe31fa2SToby Isaac       /* C' tetrahedron: {f, a, c, b} */
27883fe31fa2SToby Isaac       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
27893fe31fa2SToby Isaac       orntNew[0] = -2;
27903fe31fa2SToby Isaac       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
27913fe31fa2SToby Isaac       orntNew[1] = -2;
27923fe31fa2SToby Isaac       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
27933fe31fa2SToby Isaac       orntNew[2] = -1;
27943fe31fa2SToby Isaac       coneNew[3] = fStartNew + (cone[0] - fStart)*4 + 3;
2795e5337592SStefano Zampini       orntNew[3] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2);
2796b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
2797b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
2798b5da9499SMatthew G. Knepley #if 1
2799b5da9499SMatthew G. Knepley       if ((newp+6 < cStartNew) || (newp+6 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+6, cStartNew, cEndNew);
2800b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2801b5da9499SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
2802b5da9499SMatthew G. Knepley       }
2803b5da9499SMatthew G. Knepley #endif
28043fe31fa2SToby Isaac       /* D' tetrahedron: {f, a, e, d} */
28053fe31fa2SToby Isaac       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
28063fe31fa2SToby Isaac       orntNew[0] = -2;
2807fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
28083fe31fa2SToby Isaac       orntNew[1] = -1;
28093fe31fa2SToby Isaac       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
28103fe31fa2SToby Isaac       orntNew[2] = -2;
28113fe31fa2SToby Isaac       coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3;
2812e5337592SStefano Zampini       orntNew[3] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 1)+1) : GetTriMidEdge_Static(ornt[1], 1);
2813b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
2814b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
2815b5da9499SMatthew G. Knepley #if 1
2816b5da9499SMatthew G. Knepley       if ((newp+7 < cStartNew) || (newp+7 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+7, cStartNew, cEndNew);
2817b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2818b5da9499SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
2819b5da9499SMatthew G. Knepley       }
2820b5da9499SMatthew G. Knepley #endif
2821b5da9499SMatthew G. Knepley     }
2822b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
2823b5da9499SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2824854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
2825b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
2826b5da9499SMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
2827b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
2828b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
2829b5da9499SMatthew G. Knepley 
2830b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2831b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
2832b5da9499SMatthew G. Knepley       /* A triangle */
2833b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
2834b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2835b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
2836b5da9499SMatthew G. Knepley       orntNew[1] = -2;
2837b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
2838b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2839b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2840b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2841b5da9499SMatthew G. Knepley #if 1
2842b5da9499SMatthew G. Knepley       if ((newp+0 < fStartNew) || (newp+0 >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+0, fStartNew, fEndNew);
2843b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2844b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2845b5da9499SMatthew G. Knepley       }
2846b5da9499SMatthew G. Knepley #endif
2847b5da9499SMatthew G. Knepley       /* B triangle */
2848b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
2849b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2850b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
2851b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2852b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
2853b5da9499SMatthew G. Knepley       orntNew[2] = -2;
2854b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2855b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2856b5da9499SMatthew G. Knepley #if 1
2857b5da9499SMatthew G. Knepley       if ((newp+1 < fStartNew) || (newp+1 >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+1, fStartNew, fEndNew);
2858b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2859b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2860b5da9499SMatthew G. Knepley       }
2861b5da9499SMatthew G. Knepley #endif
2862b5da9499SMatthew G. Knepley       /* C triangle */
2863b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
2864b5da9499SMatthew G. Knepley       orntNew[0] = -2;
2865b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
2866b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2867b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
2868b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2869b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2870b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2871b5da9499SMatthew G. Knepley #if 1
2872b5da9499SMatthew G. Knepley       if ((newp+2 < fStartNew) || (newp+2 >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+2, fStartNew, fEndNew);
2873b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2874b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2875b5da9499SMatthew G. Knepley       }
2876b5da9499SMatthew G. Knepley #endif
2877b5da9499SMatthew G. Knepley       /* D triangle */
2878b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
2879b5da9499SMatthew G. Knepley       orntNew[0] = 0;
2880b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
2881b5da9499SMatthew G. Knepley       orntNew[1] = 0;
2882b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
2883b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2884b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2885b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2886b5da9499SMatthew G. Knepley #if 1
2887b5da9499SMatthew G. Knepley       if ((newp+3 < fStartNew) || (newp+3 >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+3, fStartNew, fEndNew);
2888b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2889b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2890b5da9499SMatthew G. Knepley       }
2891b5da9499SMatthew G. Knepley #endif
2892b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2893b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2894b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2895b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2896219f7b90SMatthew G. Knepley           PetscInt subf;
2897b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2898b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2899b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2900b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
2901b5da9499SMatthew G. Knepley             if (cone[c] == f) break;
2902b5da9499SMatthew G. Knepley           }
2903219f7b90SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
2904219f7b90SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
2905b5da9499SMatthew G. Knepley         }
2906b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
2907b5da9499SMatthew G. Knepley #if 1
29089ddff745SMatthew G. Knepley         if ((newp+r < fStartNew) || (newp+r >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+r, fStartNew, fEndNew);
2909b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2910b5da9499SMatthew G. Knepley           if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
2911b5da9499SMatthew G. Knepley         }
2912b5da9499SMatthew G. Knepley #endif
2913b5da9499SMatthew G. Knepley       }
2914b5da9499SMatthew G. Knepley     }
2915b5da9499SMatthew G. Knepley     /* Interior faces have 3 edges and 2 cells */
2916b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2917b5da9499SMatthew G. Knepley       PetscInt        newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8;
2918b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
2919b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
2920b5da9499SMatthew G. Knepley       PetscInt        supportNew[2];
2921b5da9499SMatthew G. Knepley 
2922b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2923b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2924b5da9499SMatthew G. Knepley       /* Face A: {c, a, d} */
2925e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
2926b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
2927e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
2928b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
2929e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2);
2930b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
2931b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2932b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2933b5da9499SMatthew G. Knepley #if 1
2934b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2935b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2936b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2937b5da9499SMatthew G. Knepley       }
2938b5da9499SMatthew G. Knepley #endif
2939b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
2940b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
2941b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2942b5da9499SMatthew G. Knepley #if 1
2943b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2944b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2945b5da9499SMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
2946b5da9499SMatthew G. Knepley       }
2947b5da9499SMatthew G. Knepley #endif
2948b5da9499SMatthew G. Knepley       ++newp;
2949b5da9499SMatthew G. Knepley       /* Face B: {a, b, e} */
2950e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
2951b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
2952e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0);
2953b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
2954e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
2955b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
2956b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2957b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2958b5da9499SMatthew G. Knepley #if 1
29594bb260e2SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2960b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2961b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2962b5da9499SMatthew G. Knepley       }
2963b5da9499SMatthew G. Knepley #endif
2964b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
2965b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
2966b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2967b5da9499SMatthew G. Knepley #if 1
2968b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2969b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2970b5da9499SMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
2971b5da9499SMatthew G. Knepley       }
2972b5da9499SMatthew G. Knepley #endif
2973b5da9499SMatthew G. Knepley       ++newp;
2974b5da9499SMatthew G. Knepley       /* Face C: {c, f, b} */
2975e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
2976b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
2977e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
2978b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
2979e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1);
2980b5da9499SMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
2981b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2982b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2983b5da9499SMatthew G. Knepley #if 1
2984b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2985b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2986b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2987b5da9499SMatthew G. Knepley       }
2988b5da9499SMatthew G. Knepley #endif
2989b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
2990b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2991b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2992b5da9499SMatthew G. Knepley #if 1
2993b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2994b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2995b5da9499SMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
2996b5da9499SMatthew G. Knepley       }
2997b5da9499SMatthew G. Knepley #endif
2998b5da9499SMatthew G. Knepley       ++newp;
2999b5da9499SMatthew G. Knepley       /* Face D: {d, e, f} */
3000e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0);
3001b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
3002e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
3003b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
3004e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
3005b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
3006b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3007b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3008b5da9499SMatthew G. Knepley #if 1
3009b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3010b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
3011b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
3012b5da9499SMatthew G. Knepley       }
3013b5da9499SMatthew G. Knepley #endif
3014b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
3015b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
3016b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3017b5da9499SMatthew G. Knepley #if 1
3018b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3019b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3020b5da9499SMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
3021b5da9499SMatthew G. Knepley       }
3022b5da9499SMatthew G. Knepley #endif
3023b5da9499SMatthew G. Knepley       ++newp;
3024b5da9499SMatthew G. Knepley       /* Face E: {d, f, a} */
3025e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
3026b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
3027b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
30284bb260e2SMatthew G. Knepley       orntNew[1] = -2;
3029e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
3030b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
3031b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3032b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3033b5da9499SMatthew G. Knepley #if 1
3034b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3035b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
3036b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
3037b5da9499SMatthew G. Knepley       }
3038b5da9499SMatthew G. Knepley #endif
3039b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
3040b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
3041b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3042b5da9499SMatthew G. Knepley #if 1
3043b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3044b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3045b5da9499SMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
3046b5da9499SMatthew G. Knepley       }
3047b5da9499SMatthew G. Knepley #endif
3048b5da9499SMatthew G. Knepley       ++newp;
3049b5da9499SMatthew G. Knepley       /* Face F: {c, a, f} */
3050e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
3051b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
3052b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
30534bb260e2SMatthew G. Knepley       orntNew[1] = 0;
3054e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
30552baf2947SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
3056b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3057b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3058b5da9499SMatthew G. Knepley #if 1
3059b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3060b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
3061b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
3062b5da9499SMatthew G. Knepley       }
3063b5da9499SMatthew G. Knepley #endif
3064b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
3065b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
3066b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3067b5da9499SMatthew G. Knepley #if 1
3068b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3069b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3070b5da9499SMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
3071b5da9499SMatthew G. Knepley       }
3072b5da9499SMatthew G. Knepley #endif
3073b5da9499SMatthew G. Knepley       ++newp;
3074b5da9499SMatthew G. Knepley       /* Face G: {e, a, f} */
3075e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
3076b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
3077b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
3078fac4ab25SMatthew G. Knepley       orntNew[1] = 0;
3079e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
3080b5da9499SMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
3081b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3082b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3083b5da9499SMatthew G. Knepley #if 1
3084b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3085b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
3086b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
3087b5da9499SMatthew G. Knepley       }
3088b5da9499SMatthew G. Knepley #endif
3089b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
3090b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
3091b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3092b5da9499SMatthew G. Knepley #if 1
3093b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3094b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3095b5da9499SMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
3096b5da9499SMatthew G. Knepley       }
3097b5da9499SMatthew G. Knepley #endif
3098b5da9499SMatthew G. Knepley       ++newp;
3099b5da9499SMatthew G. Knepley       /* Face H: {a, b, f} */
3100e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
3101b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
3102e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
3103b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
3104b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
31054bb260e2SMatthew G. Knepley       orntNew[2] = -2;
3106b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3107b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3108b5da9499SMatthew G. Knepley #if 1
3109b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3110b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
3111b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
3112b5da9499SMatthew G. Knepley       }
3113b5da9499SMatthew G. Knepley #endif
3114b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
3115b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
3116b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3117b5da9499SMatthew G. Knepley #if 1
3118b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3119b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3120b5da9499SMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
3121b5da9499SMatthew G. Knepley       }
3122b5da9499SMatthew G. Knepley #endif
3123b5da9499SMatthew G. Knepley       ++newp;
3124b5da9499SMatthew G. Knepley     }
3125b5da9499SMatthew G. Knepley     /* Split Edges have 2 vertices and the same faces as the parent */
3126b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
3127b5da9499SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
3128b5da9499SMatthew G. Knepley 
3129b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
3130b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
3131b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
3132b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
3133b5da9499SMatthew G. Knepley 
3134b5da9499SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
3135b5da9499SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
3136b5da9499SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
3137b5da9499SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
3138b5da9499SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3139b5da9499SMatthew G. Knepley #if 1
3140b5da9499SMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
3141b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
3142b5da9499SMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
3143b5da9499SMatthew G. Knepley         }
3144b5da9499SMatthew G. Knepley #endif
3145b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
3146b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
3147b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
3148b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
3149b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
3150b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
3151b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
3152b5da9499SMatthew G. Knepley             if (cone[c] == e) break;
3153b5da9499SMatthew G. Knepley           }
3154b5da9499SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
3155b5da9499SMatthew G. Knepley         }
3156b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
3157b5da9499SMatthew G. Knepley #if 1
3158b5da9499SMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
3159b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
3160b5da9499SMatthew G. Knepley           if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
3161b5da9499SMatthew G. Knepley         }
3162b5da9499SMatthew G. Knepley #endif
3163b5da9499SMatthew G. Knepley       }
3164b5da9499SMatthew G. Knepley     }
316586f0afeeSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
3166b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
3167b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
3168b5da9499SMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
3169b5da9499SMatthew G. Knepley 
3170b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
3171b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
3172b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
3173b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
3174b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
3175b5da9499SMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
3176b5da9499SMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
3177b5da9499SMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
3178b5da9499SMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
3179b5da9499SMatthew G. Knepley 
3180b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
3181b5da9499SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
3182b5da9499SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
3183b5da9499SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3184b5da9499SMatthew G. Knepley #if 1
3185b5da9499SMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
3186b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
3187b5da9499SMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
3188b5da9499SMatthew G. Knepley         }
3189b5da9499SMatthew G. Knepley #endif
3190b5da9499SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
3191b5da9499SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
3192b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
3193b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
3194b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
3195b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
3196b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
319786f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
3198e5337592SStefano Zampini           er = GetTriMidEdgeInverse_Static(ornt[c], r);
3199b5da9499SMatthew G. Knepley           if (er == eint[c]) {
3200b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
3201b5da9499SMatthew G. Knepley           } else {
3202b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
3203b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
3204b5da9499SMatthew G. Knepley           }
3205b5da9499SMatthew G. Knepley         }
3206b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
3207b5da9499SMatthew G. Knepley #if 1
3208b5da9499SMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
3209b5da9499SMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
3210b5da9499SMatthew G. Knepley           if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
3211b5da9499SMatthew G. Knepley         }
3212b5da9499SMatthew G. Knepley #endif
3213b5da9499SMatthew G. Knepley       }
3214b5da9499SMatthew G. Knepley     }
3215b5da9499SMatthew G. Knepley     /* Interior edges have 2 vertices and 4 faces */
3216b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
3217b5da9499SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
3218b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
32194a40f731SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
3220b5da9499SMatthew G. Knepley 
3221b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
3222b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
3223b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
322442525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
3225b5da9499SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
3226b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
322742525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
3228b5da9499SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
3229b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3230b5da9499SMatthew G. Knepley #if 1
3231b5da9499SMatthew G. Knepley       if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
3232b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3233b5da9499SMatthew G. Knepley         if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
3234b5da9499SMatthew G. Knepley       }
3235b5da9499SMatthew G. Knepley #endif
3236b5da9499SMatthew G. Knepley       supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
3237b5da9499SMatthew G. Knepley       supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
3238b5da9499SMatthew G. Knepley       supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
3239b5da9499SMatthew G. Knepley       supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
3240b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3241b5da9499SMatthew G. Knepley #if 1
3242b5da9499SMatthew G. Knepley       if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
3243b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3244b5da9499SMatthew G. Knepley         if ((supportNew[p] < fStartNew) || (supportNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportNew[p], fStartNew, fEndNew);
3245b5da9499SMatthew G. Knepley       }
3246b5da9499SMatthew G. Knepley #endif
3247b5da9499SMatthew G. Knepley     }
3248b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
3249b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
3250b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
3251b5da9499SMatthew G. Knepley       const PetscInt *support, *cone;
3252b5da9499SMatthew G. Knepley       PetscInt        size, s;
3253b5da9499SMatthew G. Knepley 
3254b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
3255b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
3256b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
3257b5da9499SMatthew G. Knepley         PetscInt r = 0;
3258b5da9499SMatthew G. Knepley 
3259b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
3260b5da9499SMatthew G. Knepley         if (cone[1] == v) r = 1;
3261b5da9499SMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
3262b5da9499SMatthew G. Knepley       }
3263b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
3264b5da9499SMatthew G. Knepley #if 1
3265b5da9499SMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
3266b5da9499SMatthew G. Knepley       for (p = 0; p < size; ++p) {
3267b5da9499SMatthew G. Knepley         if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
3268b5da9499SMatthew G. Knepley       }
3269b5da9499SMatthew G. Knepley #endif
3270b5da9499SMatthew G. Knepley     }
3271b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + face*2 + 0/1 supports */
3272b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
3273b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
3274b5da9499SMatthew G. Knepley       const PetscInt *cone, *support;
3275b5da9499SMatthew G. Knepley       PetscInt       *star = NULL, starSize, cellSize = 0, coneSize, size, s;
3276b5da9499SMatthew G. Knepley 
3277b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
3278b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
3279b5da9499SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
3280b5da9499SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
3281b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
3282b5da9499SMatthew G. Knepley         PetscInt r = 0;
3283b5da9499SMatthew G. Knepley 
3284b5da9499SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
3285b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
3286b5da9499SMatthew G. Knepley         for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
3287b5da9499SMatthew G. Knepley         supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
3288b5da9499SMatthew G. Knepley         supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
3289b5da9499SMatthew G. Knepley       }
3290b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
3291b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
3292b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
3293b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
3294b5da9499SMatthew G. Knepley 
3295b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
3296b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
3297b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
3298b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
3299b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
330042525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
3301b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
3302b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
3303b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
330442525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
330542525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
3306b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);}
3307b5da9499SMatthew G. Knepley         }
3308b5da9499SMatthew G. Knepley       }
3309b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
3310b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
3311b5da9499SMatthew G. Knepley #if 1
3312b5da9499SMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
3313b5da9499SMatthew G. Knepley       for (p = 0; p < 2+size*2+cellSize; ++p) {
3314b5da9499SMatthew G. Knepley         if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
3315b5da9499SMatthew G. Knepley       }
3316b5da9499SMatthew G. Knepley #endif
3317b5da9499SMatthew G. Knepley     }
3318b5da9499SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
3319b5da9499SMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
3320b5da9499SMatthew G. Knepley     break;
33219b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
33226ce3c06aSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
33236ce3c06aSMatthew G. Knepley     /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
33246ce3c06aSMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
33256ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
33266ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
33276ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
33286ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
33296ce3c06aSMatthew G. Knepley 
33306ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
33316ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
33326ce3c06aSMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
33336ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
33346ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
33356ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
33366ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
33376ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
33386ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
33396ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
33406ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
33416ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
33426ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
33436ce3c06aSMatthew G. Knepley #if 1
33446ce3c06aSMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cMaxNew);
33456ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
33466ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
33476ce3c06aSMatthew G. Knepley       }
33486ce3c06aSMatthew G. Knepley #endif
33496ce3c06aSMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
33506ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
33516ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
33526ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
33536ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
33546ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
33556ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
33566ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
33576ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
33586ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
33596ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
33606ce3c06aSMatthew G. Knepley #if 1
33616ce3c06aSMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cMaxNew);
33626ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
33636ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
33646ce3c06aSMatthew G. Knepley       }
33656ce3c06aSMatthew G. Knepley #endif
33666ce3c06aSMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
33676ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
33686ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
33696ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
33706ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
33716ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
33726ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
33736ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
33746ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
33756ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
33766ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
33776ce3c06aSMatthew G. Knepley #if 1
33786ce3c06aSMatthew G. Knepley       if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cMaxNew);
33796ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
33806ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
33816ce3c06aSMatthew G. Knepley       }
33826ce3c06aSMatthew G. Knepley #endif
33836ce3c06aSMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
33846ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
33856ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
33866ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
33876ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
33886ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
33896ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
33906ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
33916ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
33926ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
33936ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
33946ce3c06aSMatthew G. Knepley #if 1
33956ce3c06aSMatthew G. Knepley       if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cMaxNew);
33966ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
33976ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
33986ce3c06aSMatthew G. Knepley       }
33996ce3c06aSMatthew G. Knepley #endif
34006ce3c06aSMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
34016ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
34026ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
34039ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
3404e5337592SStefano Zampini       orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0);
34059ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
34069ddff745SMatthew G. Knepley       orntNew[2] = 0;
34079ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
34089ddff745SMatthew G. Knepley       orntNew[3] = 2;
34096ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
34106ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
34116ce3c06aSMatthew G. Knepley #if 1
34126ce3c06aSMatthew G. Knepley       if ((newp+4 < cStartNew) || (newp+4 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+4, cStartNew, cMaxNew);
34136ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
34146ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
34156ce3c06aSMatthew G. Knepley       }
34166ce3c06aSMatthew G. Knepley #endif
34176ce3c06aSMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
34186ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
34196ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
34209ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
34219ddff745SMatthew G. Knepley       orntNew[1] = 1;
34229ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
34236ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
34249ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
3425e5337592SStefano Zampini       orntNew[3] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 0)+1) : GetTriMidEdge_Static(ornt[3], 0);
34266ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
34276ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
34286ce3c06aSMatthew G. Knepley #if 1
34296ce3c06aSMatthew G. Knepley       if ((newp+5 < cStartNew) || (newp+5 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+5, cStartNew, cMaxNew);
34306ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
34316ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
34326ce3c06aSMatthew G. Knepley       }
34336ce3c06aSMatthew G. Knepley #endif
34346ce3c06aSMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
34356ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
34366ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
34379ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
3438e5337592SStefano Zampini       orntNew[1] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2);
34399ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
34409ddff745SMatthew G. Knepley       orntNew[2] = -3;
34419ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
34429ddff745SMatthew G. Knepley       orntNew[3] = -2;
34436ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
34446ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
34456ce3c06aSMatthew G. Knepley #if 1
34466ce3c06aSMatthew G. Knepley       if ((newp+6 < cStartNew) || (newp+6 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+6, cStartNew, cMaxNew);
34476ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
34486ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
34496ce3c06aSMatthew G. Knepley       }
34506ce3c06aSMatthew G. Knepley #endif
34516ce3c06aSMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
34526ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
34536ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
34549ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
34556ce3c06aSMatthew G. Knepley       orntNew[1] = -3;
34569ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
3457e5337592SStefano Zampini       orntNew[2] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 0)+1) : GetTriMidEdge_Static(ornt[1], 0);
34589ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
34599ddff745SMatthew G. Knepley       orntNew[3] = -3;
34606ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
34616ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
34626ce3c06aSMatthew G. Knepley #if 1
34636ce3c06aSMatthew G. Knepley       if ((newp+7 < cStartNew) || (newp+7 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+7, cStartNew, cMaxNew);
34646ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
34656ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
34666ce3c06aSMatthew G. Knepley       }
34676ce3c06aSMatthew G. Knepley #endif
34686ce3c06aSMatthew G. Knepley     }
34696ce3c06aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
34706ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
34716ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4;
3472d3a1cc75SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
34733b61eb6dSMatthew G. Knepley       PetscInt        coneNew[5], orntNew[5], o, of, i;
34746ce3c06aSMatthew G. Knepley 
34756ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
34766ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
3477d3a1cc75SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
3478084f9c62SMatthew G. Knepley       o = ornt[0] < 0 ? -1 : 1;
34796ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
34806ce3c06aSMatthew G. Knepley         coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r);
34816ce3c06aSMatthew G. Knepley         orntNew[0] = ornt[0];
34826ce3c06aSMatthew G. Knepley         coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r);
34836ce3c06aSMatthew G. Knepley         orntNew[1] = ornt[1];
3484084f9c62SMatthew G. Knepley         of = fornt[GetTriEdge_Static(ornt[0], r)]       < 0 ? -1 : 1;
34853b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], r)       + 2;
34863b61eb6dSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)]       - fMax)*2 + (o*of < 0 ? 1 : 0);
34873b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
34883b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2;
34893b61eb6dSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r);
34903b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
34913b61eb6dSMatthew G. Knepley         of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1;
34923b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2;
34933b61eb6dSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], (r+2)%3)] - fMax)*2 + (o*of < 0 ? 0 : 1);
34943b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
34956ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
34966ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
34976ce3c06aSMatthew G. Knepley #if 1
34986ce3c06aSMatthew G. Knepley         if ((newp+r < cMaxNew) || (newp+r >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", newp+r, cMaxNew, cEndNew);
34996ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
35006ce3c06aSMatthew G. Knepley           if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
35016ce3c06aSMatthew G. Knepley         }
35026ce3c06aSMatthew G. Knepley         for (p = 2; p < 5; ++p) {
35036ce3c06aSMatthew G. Knepley           if ((coneNew[p] < fMaxNew)   || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", coneNew[p], fMaxNew, fEndNew);
35046ce3c06aSMatthew G. Knepley         }
35056ce3c06aSMatthew G. Knepley #endif
35066ce3c06aSMatthew G. Knepley       }
35076ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3;
35086ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
35096ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3;
35106ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
35113b61eb6dSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1;
35126ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
35133b61eb6dSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2;
35146ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
35153b61eb6dSMatthew G. Knepley       coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0;
35166ce3c06aSMatthew G. Knepley       orntNew[4] = 0;
35176ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
35186ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
35196ce3c06aSMatthew G. Knepley #if 1
35206ce3c06aSMatthew G. Knepley       if ((newp+3 < cMaxNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", newp+3, cMaxNew, cEndNew);
35216ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
35226ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
35236ce3c06aSMatthew G. Knepley       }
35246ce3c06aSMatthew G. Knepley       for (p = 2; p < 5; ++p) {
35256ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fMaxNew)   || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", coneNew[p], fMaxNew, fEndNew);
35266ce3c06aSMatthew G. Knepley       }
35276ce3c06aSMatthew G. Knepley #endif
35286ce3c06aSMatthew G. Knepley     }
35296ce3c06aSMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
35306ce3c06aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
3531854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
35326ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
35336ce3c06aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
35346ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
35356ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
35366ce3c06aSMatthew G. Knepley 
35376ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
35386ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
35396ce3c06aSMatthew G. Knepley       /* A triangle */
35406ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
35416ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
35426ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
35436ce3c06aSMatthew G. Knepley       orntNew[1] = -2;
35446ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
35456ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
35466ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
35476ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
35486ce3c06aSMatthew G. Knepley #if 1
35496ce3c06aSMatthew G. Knepley       if ((newp+0 < fStartNew) || (newp+0 >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+0, fStartNew, fMaxNew);
35506ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
35516ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
35526ce3c06aSMatthew G. Knepley       }
35536ce3c06aSMatthew G. Knepley #endif
35546ce3c06aSMatthew G. Knepley       /* B triangle */
35556ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
35566ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
35576ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
35586ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
35596ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
35606ce3c06aSMatthew G. Knepley       orntNew[2] = -2;
35616ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
35626ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
35636ce3c06aSMatthew G. Knepley #if 1
35646ce3c06aSMatthew G. Knepley       if ((newp+1 < fStartNew) || (newp+1 >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+1, fStartNew, fMaxNew);
35656ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
35666ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
35676ce3c06aSMatthew G. Knepley       }
35686ce3c06aSMatthew G. Knepley #endif
35696ce3c06aSMatthew G. Knepley       /* C triangle */
35706ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
35716ce3c06aSMatthew G. Knepley       orntNew[0] = -2;
35726ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
35736ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
35746ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
35756ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
35766ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
35776ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
35786ce3c06aSMatthew G. Knepley #if 1
35796ce3c06aSMatthew G. Knepley       if ((newp+2 < fStartNew) || (newp+2 >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+2, fStartNew, fMaxNew);
35806ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
35816ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
35826ce3c06aSMatthew G. Knepley       }
35836ce3c06aSMatthew G. Knepley #endif
35846ce3c06aSMatthew G. Knepley       /* D triangle */
35856ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
35866ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
35876ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
35886ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
35896ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
35906ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
35916ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
35926ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
35936ce3c06aSMatthew G. Knepley #if 1
35946ce3c06aSMatthew G. Knepley       if ((newp+3 < fStartNew) || (newp+3 >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+3, fStartNew, fMaxNew);
35956ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
35966ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
35976ce3c06aSMatthew G. Knepley       }
35986ce3c06aSMatthew G. Knepley #endif
35996ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
36006ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
36016ce3c06aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
36026ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
36039ddff745SMatthew G. Knepley           PetscInt subf;
36046ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
36056ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
36066ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
36076ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
36086ce3c06aSMatthew G. Knepley             if (cone[c] == f) break;
36096ce3c06aSMatthew G. Knepley           }
36109ddff745SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
36116ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
36129ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
36136ce3c06aSMatthew G. Knepley           } else {
36149ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf);
36156ce3c06aSMatthew G. Knepley           }
36166ce3c06aSMatthew G. Knepley         }
36176ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
36186ce3c06aSMatthew G. Knepley #if 1
36199ddff745SMatthew G. Knepley         if ((newp+r < fStartNew) || (newp+r >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+r, fStartNew, fMaxNew);
36206ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
36216ce3c06aSMatthew G. Knepley           if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior or hybrid cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
36226ce3c06aSMatthew G. Knepley         }
36236ce3c06aSMatthew G. Knepley #endif
36246ce3c06aSMatthew G. Knepley       }
36256ce3c06aSMatthew G. Knepley     }
36266ce3c06aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
36276ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
36286ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8;
36296ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
36306ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
36316ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
36326ce3c06aSMatthew G. Knepley 
36336ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
36346ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
36356ce3c06aSMatthew G. Knepley       /* Face A: {c, a, d} */
3636e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
36376ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
3638e5337592SStefano Zampini       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
36396ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
3640e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2);
36416ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
36426ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
36436ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
36446ce3c06aSMatthew G. Knepley #if 1
36456ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
36466ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
36476ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
36486ce3c06aSMatthew G. Knepley       }
36496ce3c06aSMatthew G. Knepley #endif
36506ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
36516ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
36526ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
36536ce3c06aSMatthew G. Knepley #if 1
36546ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
36556ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
36566ce3c06aSMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
36576ce3c06aSMatthew G. Knepley       }
36586ce3c06aSMatthew G. Knepley #endif
36596ce3c06aSMatthew G. Knepley       ++newp;
36606ce3c06aSMatthew G. Knepley       /* Face B: {a, b, e} */
3661e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
36626ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
3663e5337592SStefano Zampini       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0);
36646ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
3665e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
36666ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
36676ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
36686ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
36696ce3c06aSMatthew G. Knepley #if 1
36706ce3c06aSMatthew G. Knepley       if ((newp+1 < fStartNew) || (newp+1 >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+1, fStartNew, fMaxNew);
36716ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
36726ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
36736ce3c06aSMatthew G. Knepley       }
36746ce3c06aSMatthew G. Knepley #endif
36756ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
36766ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
36776ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
36786ce3c06aSMatthew G. Knepley #if 1
36796ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
36806ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
36816ce3c06aSMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
36826ce3c06aSMatthew G. Knepley       }
36836ce3c06aSMatthew G. Knepley #endif
36846ce3c06aSMatthew G. Knepley       ++newp;
36856ce3c06aSMatthew G. Knepley       /* Face C: {c, f, b} */
3686e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
36876ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
3688e5337592SStefano Zampini       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
36896ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
3690e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1);
36916ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
36926ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
36936ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
36946ce3c06aSMatthew G. Knepley #if 1
36956ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
36966ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
36976ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
36986ce3c06aSMatthew G. Knepley       }
36996ce3c06aSMatthew G. Knepley #endif
37006ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
37016ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
37026ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
37036ce3c06aSMatthew G. Knepley #if 1
37046ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
37056ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
37066ce3c06aSMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
37076ce3c06aSMatthew G. Knepley       }
37086ce3c06aSMatthew G. Knepley #endif
37096ce3c06aSMatthew G. Knepley       ++newp;
37106ce3c06aSMatthew G. Knepley       /* Face D: {d, e, f} */
3711e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0);
37126ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
3713e5337592SStefano Zampini       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
37146ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
3715e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
37166ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
37176ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37186ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
37196ce3c06aSMatthew G. Knepley #if 1
37206ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
37216ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
37226ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
37236ce3c06aSMatthew G. Knepley       }
37246ce3c06aSMatthew G. Knepley #endif
37256ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
37266ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
37276ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
37286ce3c06aSMatthew G. Knepley #if 1
37296ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
37306ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
37316ce3c06aSMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
37326ce3c06aSMatthew G. Knepley       }
37336ce3c06aSMatthew G. Knepley #endif
37346ce3c06aSMatthew G. Knepley       ++newp;
37356ce3c06aSMatthew G. Knepley       /* Face E: {d, f, a} */
3736e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
37376ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
37386ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
37399ddff745SMatthew G. Knepley       orntNew[1] = -2;
3740e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
37416ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
37426ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37436ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
37446ce3c06aSMatthew G. Knepley #if 1
37456ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
37466ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
37476ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
37486ce3c06aSMatthew G. Knepley       }
37496ce3c06aSMatthew G. Knepley #endif
37506ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
37516ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
37526ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
37536ce3c06aSMatthew G. Knepley #if 1
37546ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
37556ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
37566ce3c06aSMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
37576ce3c06aSMatthew G. Knepley       }
37586ce3c06aSMatthew G. Knepley #endif
37596ce3c06aSMatthew G. Knepley       ++newp;
37606ce3c06aSMatthew G. Knepley       /* Face F: {c, a, f} */
3761e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
37626ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
37636ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
37649ddff745SMatthew G. Knepley       orntNew[1] = 0;
3765e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
37669ddff745SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
37676ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37686ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
37696ce3c06aSMatthew G. Knepley #if 1
37706ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
37716ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
37726ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
37736ce3c06aSMatthew G. Knepley       }
37746ce3c06aSMatthew G. Knepley #endif
37756ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
37766ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
37776ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
37786ce3c06aSMatthew G. Knepley #if 1
37796ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
37806ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
37816ce3c06aSMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
37826ce3c06aSMatthew G. Knepley       }
37836ce3c06aSMatthew G. Knepley #endif
37846ce3c06aSMatthew G. Knepley       ++newp;
37856ce3c06aSMatthew G. Knepley       /* Face G: {e, a, f} */
3786e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
37876ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
37886ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
37899ddff745SMatthew G. Knepley       orntNew[1] = 0;
3790e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
37916ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
37926ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37936ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
37946ce3c06aSMatthew G. Knepley #if 1
37956ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
37966ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
37976ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
37986ce3c06aSMatthew G. Knepley       }
37996ce3c06aSMatthew G. Knepley #endif
38006ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
38016ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
38026ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
38036ce3c06aSMatthew G. Knepley #if 1
38046ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
38056ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
38066ce3c06aSMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
38076ce3c06aSMatthew G. Knepley       }
38086ce3c06aSMatthew G. Knepley #endif
38096ce3c06aSMatthew G. Knepley       ++newp;
38106ce3c06aSMatthew G. Knepley       /* Face H: {a, b, f} */
3811e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
38126ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
3813e5337592SStefano Zampini       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
38146ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
38156ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
38169ddff745SMatthew G. Knepley       orntNew[2] = -2;
38176ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
38186ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
38196ce3c06aSMatthew G. Knepley #if 1
38206ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
38216ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
38226ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
38236ce3c06aSMatthew G. Knepley       }
38246ce3c06aSMatthew G. Knepley #endif
38256ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
38266ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
38276ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
38286ce3c06aSMatthew G. Knepley #if 1
38296ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
38306ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
38316ce3c06aSMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
38326ce3c06aSMatthew G. Knepley       }
38336ce3c06aSMatthew G. Knepley #endif
38346ce3c06aSMatthew G. Knepley       ++newp;
38356ce3c06aSMatthew G. Knepley     }
38366ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
38376ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
38386ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
38396ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
38406ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
38416ce3c06aSMatthew G. Knepley 
38426ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
38436ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
38446ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
38456ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
38466ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
38476ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
38486ce3c06aSMatthew G. Knepley 
38496ce3c06aSMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
38506ce3c06aSMatthew G. Knepley         orntNew[0]   = ornt[0];
38516ce3c06aSMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
38526ce3c06aSMatthew G. Knepley         orntNew[1]   = ornt[1];
38536ce3c06aSMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax);
38546ce3c06aSMatthew G. Knepley         orntNew[2+r] = 0;
38556ce3c06aSMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd      - eMax) + (f - fMax);
38566ce3c06aSMatthew G. Knepley         orntNew[3-r] = 0;
38576ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
38586ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
38596ce3c06aSMatthew G. Knepley #if 1
38606ce3c06aSMatthew G. Knepley         if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew);
38616ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
38626ce3c06aSMatthew G. Knepley           if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
38636ce3c06aSMatthew G. Knepley         }
38646ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
38656ce3c06aSMatthew G. Knepley           if ((coneNew[p] < eMaxNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", coneNew[p], eMaxNew, eEndNew);
38666ce3c06aSMatthew G. Knepley         }
38676ce3c06aSMatthew G. Knepley #endif
38686ce3c06aSMatthew G. Knepley         for (s = 0; s < size; ++s) {
3869d3a1cc75SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
3870084f9c62SMatthew G. Knepley           PetscInt        o, of;
38716ce3c06aSMatthew G. Knepley 
38726ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
38736ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
3874084f9c62SMatthew G. Knepley           o = orntCell[0] < 0 ? -1 : 1;
38756ce3c06aSMatthew G. Knepley           for (c = 2; c < 5; ++c) if (coneCell[c] == f) break;
38766ce3c06aSMatthew G. Knepley           if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]);
3877d3a1cc75SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
3878084f9c62SMatthew G. Knepley           of = fornt[c-2] < 0 ? -1 : 1;
3879084f9c62SMatthew G. Knepley           supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3;
38806ce3c06aSMatthew G. Knepley         }
38816ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
38826ce3c06aSMatthew G. Knepley #if 1
38836ce3c06aSMatthew G. Knepley         if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew);
38846ce3c06aSMatthew G. Knepley         for (p = 0; p < size; ++p) {
38856ce3c06aSMatthew G. Knepley           if ((supportNew[p] < cMaxNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", supportNew[p], cMaxNew, cEndNew);
38866ce3c06aSMatthew G. Knepley         }
38876ce3c06aSMatthew G. Knepley #endif
38886ce3c06aSMatthew G. Knepley       }
38896ce3c06aSMatthew G. Knepley     }
38906ce3c06aSMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
38916ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
38926ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3;
38936ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
38946ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
38956ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
38966ce3c06aSMatthew G. Knepley 
38976ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
38986ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
38996ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
3900b598a9d5SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3;
39016ce3c06aSMatthew G. Knepley         orntNew[0] = 0;
3902b598a9d5SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3;
39036ce3c06aSMatthew G. Knepley         orntNew[1] = 0;
3904b598a9d5SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax);
39056ce3c06aSMatthew G. Knepley         orntNew[2] = 0;
3906b598a9d5SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r]       - fMax);
39076ce3c06aSMatthew G. Knepley         orntNew[3] = 0;
39086ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
39096ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
39106ce3c06aSMatthew G. Knepley #if 1
39116ce3c06aSMatthew G. Knepley         if ((newp+r < fMaxNew) || (newp+r >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp+r, fMaxNew, fEndNew);
39126ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
39136ce3c06aSMatthew G. Knepley           if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
39146ce3c06aSMatthew G. Knepley         }
39156ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
39166ce3c06aSMatthew G. Knepley           if ((coneNew[p] < eMaxNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", coneNew[p], eMaxNew, eEndNew);
39176ce3c06aSMatthew G. Knepley         }
39186ce3c06aSMatthew G. Knepley #endif
39196ce3c06aSMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r);
39206ce3c06aSMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3;
39216ce3c06aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
39226ce3c06aSMatthew G. Knepley #if 1
39236ce3c06aSMatthew G. Knepley         if ((newp+r < fMaxNew) || (newp+r >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp+r, fMaxNew, fEndNew);
39246ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
39256ce3c06aSMatthew G. Knepley           if ((supportNew[p] < cMaxNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", supportNew[p], cMaxNew, cEndNew);
39266ce3c06aSMatthew G. Knepley         }
39276ce3c06aSMatthew G. Knepley #endif
39286ce3c06aSMatthew G. Knepley       }
39296ce3c06aSMatthew G. Knepley     }
39306ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
39316ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
39326ce3c06aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
39336ce3c06aSMatthew G. Knepley 
39346ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
39356ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
39366ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
39376ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
39386ce3c06aSMatthew G. Knepley 
39396ce3c06aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
39406ce3c06aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
39416ce3c06aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
39426ce3c06aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
39436ce3c06aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
39446ce3c06aSMatthew G. Knepley #if 1
39456ce3c06aSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
39466ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
39476ce3c06aSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
39486ce3c06aSMatthew G. Knepley         }
39496ce3c06aSMatthew G. Knepley #endif
39506ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
39516ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
39526ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
39536ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
39546ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
39556ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
39566ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == e) break;
39576ce3c06aSMatthew G. Knepley           if (support[s] < fMax) {
39586ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
39596ce3c06aSMatthew G. Knepley           } else {
39606ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
39616ce3c06aSMatthew G. Knepley           }
39626ce3c06aSMatthew G. Knepley         }
39636ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
39646ce3c06aSMatthew G. Knepley #if 1
39656ce3c06aSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
39666ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
39676ce3c06aSMatthew G. Knepley           if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior or hybrid face [%d, %d)", supportRef[p], fStartNew, fEndNew);
39686ce3c06aSMatthew G. Knepley         }
39696ce3c06aSMatthew G. Knepley #endif
39706ce3c06aSMatthew G. Knepley       }
39716ce3c06aSMatthew G. Knepley     }
39726ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
39736ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
39746ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
39756ce3c06aSMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
39766ce3c06aSMatthew G. Knepley 
39776ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
39786ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
39796ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
39806ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
39816ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
39826ce3c06aSMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
39836ce3c06aSMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
39846ce3c06aSMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
39856ce3c06aSMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
39866ce3c06aSMatthew G. Knepley 
39876ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
39886ce3c06aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
39896ce3c06aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
39906ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
39916ce3c06aSMatthew G. Knepley #if 1
39926ce3c06aSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
39936ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
39946ce3c06aSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
39956ce3c06aSMatthew G. Knepley         }
39966ce3c06aSMatthew G. Knepley #endif
39976ce3c06aSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
39986ce3c06aSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
39996ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
40006ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
40016ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
40026ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
40036ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
40046ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
40056ce3c06aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
4006e5337592SStefano Zampini             er = GetTriMidEdgeInverse_Static(ornt[c], r);
40076ce3c06aSMatthew G. Knepley             if (er == eint[c]) {
40086ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
40096ce3c06aSMatthew G. Knepley             } else {
40106ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
40116ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
40126ce3c06aSMatthew G. Knepley             }
40136ce3c06aSMatthew G. Knepley           } else {
4014b598a9d5SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3;
40156ce3c06aSMatthew G. Knepley           }
40166ce3c06aSMatthew G. Knepley         }
40176ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
40186ce3c06aSMatthew G. Knepley #if 1
40196ce3c06aSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
40206ce3c06aSMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
40216ce3c06aSMatthew G. Knepley           if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior or hybrid face [%d, %d)", supportRef[p], fStartNew, fEndNew);
40226ce3c06aSMatthew G. Knepley         }
40236ce3c06aSMatthew G. Knepley #endif
40246ce3c06aSMatthew G. Knepley       }
40256ce3c06aSMatthew G. Knepley     }
40266ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
40276ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
40286ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
40296ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
40306ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
40316ce3c06aSMatthew G. Knepley 
40326ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
40336ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
40346ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
40356ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
40366ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
40376ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
40386ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
40396ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
40406ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
40416ce3c06aSMatthew G. Knepley #if 1
40426ce3c06aSMatthew G. Knepley       if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
40436ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
40446ce3c06aSMatthew G. Knepley         if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
40456ce3c06aSMatthew G. Knepley       }
40466ce3c06aSMatthew G. Knepley #endif
40476ce3c06aSMatthew G. Knepley       supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
40486ce3c06aSMatthew G. Knepley       supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
40496ce3c06aSMatthew G. Knepley       supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
40506ce3c06aSMatthew G. Knepley       supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
40516ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
40526ce3c06aSMatthew G. Knepley #if 1
40536ce3c06aSMatthew G. Knepley       if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
40546ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
40556ce3c06aSMatthew G. Knepley         if ((supportNew[p] < fStartNew) || (supportNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportNew[p], fStartNew, fMaxNew);
40566ce3c06aSMatthew G. Knepley       }
40576ce3c06aSMatthew G. Knepley #endif
40586ce3c06aSMatthew G. Knepley     }
40596ce3c06aSMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
40606ce3c06aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
40616ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
40626ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
40636ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
40646ce3c06aSMatthew G. Knepley 
40656ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
40666ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
40676ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
40686ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
40696ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
40706ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
40716ce3c06aSMatthew G. Knepley #if 1
40726ce3c06aSMatthew G. Knepley       if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
40736ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
40746ce3c06aSMatthew G. Knepley         if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
40756ce3c06aSMatthew G. Knepley       }
40766ce3c06aSMatthew G. Knepley #endif
40776ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
40786ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
40796ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
40806ce3c06aSMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
40816ce3c06aSMatthew G. Knepley         if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]);
40826ce3c06aSMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2;
40836ce3c06aSMatthew G. Knepley       }
40846ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
40856ce3c06aSMatthew G. Knepley #if 1
40866ce3c06aSMatthew G. Knepley       if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
40876ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
40886ce3c06aSMatthew G. Knepley         if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", supportRef[p], fMaxNew, fEndNew);
40896ce3c06aSMatthew G. Knepley       }
40906ce3c06aSMatthew G. Knepley #endif
40916ce3c06aSMatthew G. Knepley     }
40926ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
40936ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
40946ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
4095623f4348SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
40966ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
40976ce3c06aSMatthew G. Knepley 
40986ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
40996ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
41006ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
41016ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
41026ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
41036ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
41046ce3c06aSMatthew G. Knepley #if 1
41056ce3c06aSMatthew G. Knepley       if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
41066ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
41076ce3c06aSMatthew G. Knepley         if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
41086ce3c06aSMatthew G. Knepley       }
41096ce3c06aSMatthew G. Knepley #endif
41106ce3c06aSMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0;
41116ce3c06aSMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1;
41126ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
41136ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
41146ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
4115623f4348SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
41166ce3c06aSMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
41176ce3c06aSMatthew G. Knepley         if ((c < 2) || (c >= csize)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Hybrid face %d is not in cone of hybrid cell %d", f, support[s]);
4118b598a9d5SMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2;
4119b598a9d5SMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3;
41206ce3c06aSMatthew G. Knepley       }
41216ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
41226ce3c06aSMatthew G. Knepley #if 1
41236ce3c06aSMatthew G. Knepley       if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
41246ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
41256ce3c06aSMatthew G. Knepley         if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", supportRef[p], fMaxNew, fEndNew);
41266ce3c06aSMatthew G. Knepley       }
41276ce3c06aSMatthew G. Knepley #endif
41286ce3c06aSMatthew G. Knepley     }
41296ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
41306ce3c06aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
41316ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
41326ce3c06aSMatthew G. Knepley       const PetscInt *support, *cone;
41336ce3c06aSMatthew G. Knepley       PetscInt        size, s;
41346ce3c06aSMatthew G. Knepley 
41356ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
41366ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
41376ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
41386ce3c06aSMatthew G. Knepley         PetscInt r = 0;
41396ce3c06aSMatthew G. Knepley 
41406ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
41416ce3c06aSMatthew G. Knepley         if (cone[1] == v) r = 1;
41426ce3c06aSMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
41436ce3c06aSMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax);
41446ce3c06aSMatthew G. Knepley       }
41456ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
41466ce3c06aSMatthew G. Knepley #if 1
41476ce3c06aSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
41486ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
41496ce3c06aSMatthew G. Knepley         if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior or hybrid edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
41506ce3c06aSMatthew G. Knepley       }
41516ce3c06aSMatthew G. Knepley #endif
41526ce3c06aSMatthew G. Knepley     }
41536ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
41546ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
41556ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
41566ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support;
41576ce3c06aSMatthew G. Knepley       PetscInt       *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s;
41586ce3c06aSMatthew G. Knepley 
41596ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
41606ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
41616ce3c06aSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
41626ce3c06aSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
41636ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
41646ce3c06aSMatthew G. Knepley         PetscInt r = 0;
41656ce3c06aSMatthew G. Knepley 
41666ce3c06aSMatthew G. Knepley         if (support[s] < fMax) {
41676ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
41686ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
41696ce3c06aSMatthew G. Knepley           for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
41706ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
41716ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
41726ce3c06aSMatthew G. Knepley           faceSize += 2;
41736ce3c06aSMatthew G. Knepley         } else {
41746ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax);
41756ce3c06aSMatthew G. Knepley           ++faceSize;
41766ce3c06aSMatthew G. Knepley         }
41776ce3c06aSMatthew G. Knepley       }
41786ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
41796ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
41806ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
41816ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
41826ce3c06aSMatthew G. Knepley 
41836ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
41846ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
41856ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
41866ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
41876ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
41886ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
41896ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
41906ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
41916ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
41926ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
41936ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
41946ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);}
41956ce3c06aSMatthew G. Knepley         }
41966ce3c06aSMatthew G. Knepley       }
41976ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
41986ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
41996ce3c06aSMatthew G. Knepley #if 1
42006ce3c06aSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
42016ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+faceSize+cellSize; ++p) {
42026ce3c06aSMatthew G. Knepley         if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior or hybrid edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
42036ce3c06aSMatthew G. Knepley       }
42046ce3c06aSMatthew G. Knepley #endif
42056ce3c06aSMatthew G. Knepley     }
42066ce3c06aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
42076ce3c06aSMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
42086ce3c06aSMatthew G. Knepley     break;
4209e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_3D:
4210e5337592SStefano Zampini     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
4211e5337592SStefano Zampini     /* All cells have 6 faces */
4212e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
4213e5337592SStefano Zampini       const PetscInt  newp = cStartNew + (c - cStart)*4;
4214e5337592SStefano Zampini       const PetscInt *cone, *ornt;
4215e5337592SStefano Zampini       PetscInt        coneNew[6];
4216e5337592SStefano Zampini       PetscInt        orntNew[6];
4217e5337592SStefano Zampini 
4218e5337592SStefano Zampini       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
4219e5337592SStefano Zampini       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
4220e5337592SStefano Zampini       /* A hex */
4221e5337592SStefano Zampini       coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */
4222e5337592SStefano Zampini       orntNew[0] = ornt[0] < 0 ? -1 : 1;
4223e5337592SStefano Zampini       coneNew[1] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 3;               /* T */
4224e5337592SStefano Zampini       orntNew[1] = -4;
4225e5337592SStefano Zampini       coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */
4226e5337592SStefano Zampini       orntNew[2] = ornt[2] < 0 ? -1 : 1;
4227e5337592SStefano Zampini       coneNew[3] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 0;               /* K */
4228e5337592SStefano Zampini       orntNew[3] = -1;
4229e5337592SStefano Zampini       coneNew[4] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 2;               /* R */
4230e5337592SStefano Zampini       orntNew[4] = 0;
4231e5337592SStefano Zampini       coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */
4232e5337592SStefano Zampini       orntNew[5] = ornt[1] < 0 ? -1 : 1;
4233e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
4234e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
4235e5337592SStefano Zampini #if 1
4236e5337592SStefano 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);
4237e5337592SStefano Zampini       for (p = 0; p < 6; ++p) {
4238e5337592SStefano 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);
4239e5337592SStefano Zampini       }
4240e5337592SStefano Zampini #endif
4241e5337592SStefano Zampini       /* B hex */
4242e5337592SStefano Zampini       coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */
4243e5337592SStefano Zampini       orntNew[0] = ornt[0] < 0 ? -2 : 0;
4244e5337592SStefano Zampini       coneNew[1] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 4;               /* T */
4245e5337592SStefano Zampini       orntNew[1] = 0;
4246e5337592SStefano Zampini       coneNew[2] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 0;               /* F */
4247e5337592SStefano Zampini       orntNew[2] = 0;
4248e5337592SStefano Zampini       coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */
4249e5337592SStefano Zampini       orntNew[3] = ornt[3] < 0 ? -2 : 0;
4250e5337592SStefano Zampini       coneNew[4] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 1;               /* R */
4251e5337592SStefano Zampini       orntNew[4] = 0;
4252e5337592SStefano Zampini       coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */
4253e5337592SStefano Zampini       orntNew[5] = ornt[1] < 0 ? -4 : 2;
4254e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
4255e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
4256e5337592SStefano Zampini #if 1
4257e5337592SStefano 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);
4258e5337592SStefano Zampini       for (p = 0; p < 6; ++p) {
4259e5337592SStefano 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);
4260e5337592SStefano Zampini       }
4261e5337592SStefano Zampini #endif
4262e5337592SStefano Zampini       /* C hex */
4263e5337592SStefano Zampini       coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */
4264e5337592SStefano Zampini       orntNew[0] = ornt[0] < 0 ? -4 : 2;
4265e5337592SStefano Zampini       coneNew[1] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 5;               /* T */
4266e5337592SStefano Zampini       orntNew[1] = -4;
4267e5337592SStefano Zampini       coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */
4268e5337592SStefano Zampini       orntNew[2] = ornt[2] < 0 ? -2 : 0;
4269e5337592SStefano Zampini       coneNew[3] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 1;               /* K */
4270e5337592SStefano Zampini       orntNew[3] = -1;
4271e5337592SStefano Zampini       coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */
4272e5337592SStefano Zampini       orntNew[4] = ornt[3] < 0 ? -1 : 1;
4273e5337592SStefano Zampini       coneNew[5] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 2;               /* L */
4274e5337592SStefano Zampini       orntNew[5] = -4;
4275e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
4276e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
4277e5337592SStefano Zampini #if 1
4278e5337592SStefano 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);
4279e5337592SStefano Zampini       for (p = 0; p < 6; ++p) {
4280e5337592SStefano 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);
4281e5337592SStefano Zampini       }
4282e5337592SStefano Zampini #endif
4283e5337592SStefano Zampini       /* D hex */
4284e5337592SStefano Zampini       coneNew[0] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 3;               /* B */
4285e5337592SStefano Zampini       orntNew[0] = 0;
4286e5337592SStefano Zampini       coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */
4287e5337592SStefano Zampini       orntNew[1] = ornt[3] < 0 ? -1 : 1;
4288e5337592SStefano Zampini       coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */
4289e5337592SStefano Zampini       orntNew[2] = ornt[2] < 0 ? -4 : 2;
4290e5337592SStefano Zampini       coneNew[3] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 4;               /* K */
4291e5337592SStefano Zampini       orntNew[3] = -1;
4292e5337592SStefano Zampini       coneNew[4] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 5;               /* R */
4293e5337592SStefano Zampini       orntNew[4] = 0;
4294e5337592SStefano Zampini       coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */
4295e5337592SStefano Zampini       orntNew[5] = ornt[1] < 0 ? -2 : 0;
4296e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
4297e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
4298e5337592SStefano Zampini #if 1
4299e5337592SStefano 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);
4300e5337592SStefano Zampini       for (p = 0; p < 6; ++p) {
4301e5337592SStefano 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);
4302e5337592SStefano Zampini       }
4303e5337592SStefano Zampini #endif
4304e5337592SStefano Zampini     }
4305e5337592SStefano Zampini     /* Split faces have 4 edges and the same cells as the parent */
4306e5337592SStefano Zampini     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
4307e5337592SStefano Zampini     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
4308e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
4309e5337592SStefano Zampini       const PetscInt  newp = fStartNew + (f - fStart)*3;
4310e5337592SStefano Zampini       const PetscInt *cone, *ornt, *support;
4311e5337592SStefano Zampini       PetscInt        coneNew[4], orntNew[4], coneSize, supportSize, s;
4312e5337592SStefano Zampini 
4313e5337592SStefano Zampini       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
4314e5337592SStefano Zampini       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
4315e5337592SStefano Zampini       /* A quad */
4316e5337592SStefano Zampini       coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
4317e5337592SStefano Zampini       orntNew[0] = ornt[2];
4318e5337592SStefano Zampini       coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
4319e5337592SStefano Zampini       orntNew[1] = ornt[0];
4320e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
4321e5337592SStefano Zampini       orntNew[2] = 0;
4322e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
4323e5337592SStefano Zampini       orntNew[3] = -2;
4324e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
4325e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
4326e5337592SStefano Zampini #if 1
4327e5337592SStefano 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);
4328e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4329e5337592SStefano 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);
4330e5337592SStefano Zampini       }
4331e5337592SStefano Zampini #endif
4332e5337592SStefano Zampini       /* B quad */
4333e5337592SStefano Zampini       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
4334e5337592SStefano Zampini       orntNew[0] = ornt[0];
4335e5337592SStefano Zampini       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
4336e5337592SStefano Zampini       orntNew[1] = ornt[1];
4337e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
4338e5337592SStefano Zampini       orntNew[2] = 0;
4339e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
4340e5337592SStefano Zampini       orntNew[3] = -2;
4341e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
4342e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
4343e5337592SStefano Zampini #if 1
4344e5337592SStefano 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);
4345e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4346e5337592SStefano 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);
4347e5337592SStefano Zampini       }
4348e5337592SStefano Zampini #endif
4349e5337592SStefano Zampini       /* C quad */
4350e5337592SStefano Zampini       coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
4351e5337592SStefano Zampini       orntNew[0] = ornt[1];
4352e5337592SStefano Zampini       coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
4353e5337592SStefano Zampini       orntNew[1] = ornt[2];
4354e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
4355e5337592SStefano Zampini       orntNew[2] = 0;
4356e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
4357e5337592SStefano Zampini       orntNew[3] = -2;
4358e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
4359e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
4360e5337592SStefano Zampini #if 1
4361e5337592SStefano 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);
4362e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4363e5337592SStefano 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);
4364e5337592SStefano Zampini       }
4365e5337592SStefano Zampini #endif
4366e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
4367e5337592SStefano Zampini       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
4368e5337592SStefano Zampini       for (r = 0; r < 3; ++r) {
4369e5337592SStefano Zampini         for (s = 0; s < supportSize; ++s) {
4370e5337592SStefano Zampini           PetscInt subf;
4371e5337592SStefano Zampini           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
4372e5337592SStefano Zampini           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4373e5337592SStefano Zampini           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
4374e5337592SStefano Zampini           for (c = 0; c < coneSize; ++c) {
4375e5337592SStefano Zampini             if (cone[c] == f) break;
4376e5337592SStefano Zampini           }
4377e5337592SStefano Zampini           subf = GetTriSubfaceInverse_Static(ornt[c], r);
4378e5337592SStefano Zampini           supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf];
4379e5337592SStefano Zampini         }
4380e5337592SStefano Zampini         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
4381e5337592SStefano Zampini #if 1
4382e5337592SStefano 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);
4383e5337592SStefano Zampini         for (p = 0; p < supportSize; ++p) {
4384e5337592SStefano 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);
4385e5337592SStefano Zampini         }
4386e5337592SStefano Zampini #endif
4387e5337592SStefano Zampini       }
4388e5337592SStefano Zampini     }
4389e5337592SStefano Zampini     /* Interior faces have 4 edges and 2 cells */
4390e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
4391e5337592SStefano Zampini       PetscInt        newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6;
4392e5337592SStefano Zampini       const PetscInt *cone, *ornt;
4393e5337592SStefano Zampini       PetscInt        coneNew[4], orntNew[4];
4394e5337592SStefano Zampini       PetscInt        supportNew[2];
4395e5337592SStefano Zampini 
4396e5337592SStefano Zampini       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
4397e5337592SStefano Zampini       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
4398e5337592SStefano Zampini       /* Face {a, g, m, h} */
4399e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0);
4400e5337592SStefano Zampini       orntNew[0] = 0;
4401e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
4402e5337592SStefano Zampini       orntNew[1] = 0;
4403e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
4404e5337592SStefano Zampini       orntNew[2] = -2;
4405e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2);
4406e5337592SStefano Zampini       orntNew[3] = -2;
4407e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4408e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4409e5337592SStefano Zampini #if 1
4410e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4411e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4412e5337592SStefano 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);
4413e5337592SStefano Zampini       }
4414e5337592SStefano Zampini #endif
4415e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 0;
4416e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 1;
4417e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4418e5337592SStefano Zampini #if 1
4419e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4420e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4421e5337592SStefano 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);
4422e5337592SStefano Zampini       }
4423e5337592SStefano Zampini #endif
4424e5337592SStefano Zampini       ++newp;
4425e5337592SStefano Zampini       /* Face {g, b, l , m} */
4426e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1);
4427e5337592SStefano Zampini       orntNew[0] = -2;
4428e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0);
4429e5337592SStefano Zampini       orntNew[1] = 0;
4430e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
4431e5337592SStefano Zampini       orntNew[2] = 0;
4432e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
4433e5337592SStefano Zampini       orntNew[3] = -2;
4434e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4435e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4436e5337592SStefano Zampini #if 1
4437e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4438e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4439e5337592SStefano 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);
4440e5337592SStefano Zampini       }
4441e5337592SStefano Zampini #endif
4442e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 1;
4443e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 2;
4444e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4445e5337592SStefano Zampini #if 1
4446e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4447e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4448e5337592SStefano 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);
4449e5337592SStefano Zampini       }
4450e5337592SStefano Zampini #endif
4451e5337592SStefano Zampini       ++newp;
4452e5337592SStefano Zampini       /* Face {c, g, m, i} */
4453e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2);
4454e5337592SStefano Zampini       orntNew[0] = 0;
4455e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
4456e5337592SStefano Zampini       orntNew[1] = 0;
4457e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
4458e5337592SStefano Zampini       orntNew[2] = -2;
4459e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0);
4460e5337592SStefano Zampini       orntNew[3] = -2;
4461e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4462e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4463e5337592SStefano Zampini #if 1
4464e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4465e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4466e5337592SStefano 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);
4467e5337592SStefano Zampini       }
4468e5337592SStefano Zampini #endif
4469e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 0;
4470e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 2;
4471e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4472e5337592SStefano Zampini #if 1
4473e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4474e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4475e5337592SStefano 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);
4476e5337592SStefano Zampini       }
4477e5337592SStefano Zampini #endif
4478e5337592SStefano Zampini       ++newp;
4479e5337592SStefano Zampini       /* Face {d, h, m, i} */
4480e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0);
4481e5337592SStefano Zampini       orntNew[0] = 0;
4482e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
4483e5337592SStefano Zampini       orntNew[1] = 0;
4484e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
4485e5337592SStefano Zampini       orntNew[2] = -2;
4486e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2);
4487e5337592SStefano Zampini       orntNew[3] = -2;
4488e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4489e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4490e5337592SStefano Zampini #if 1
4491e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4492e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4493e5337592SStefano 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);
4494e5337592SStefano Zampini       }
4495e5337592SStefano Zampini #endif
4496e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 0;
4497e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 3;
4498e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4499e5337592SStefano Zampini #if 1
4500e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4501e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4502e5337592SStefano 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);
4503e5337592SStefano Zampini       }
4504e5337592SStefano Zampini #endif
4505e5337592SStefano Zampini       ++newp;
4506e5337592SStefano Zampini       /* Face {h, m, l, e} */
4507e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
4508e5337592SStefano Zampini       orntNew[0] = 0;
4509e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
4510e5337592SStefano Zampini       orntNew[1] = -2;
4511e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1);
4512e5337592SStefano Zampini       orntNew[2] = -2;
4513e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1);
4514e5337592SStefano Zampini       orntNew[3] = 0;
4515e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4516e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4517e5337592SStefano Zampini #if 1
4518e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4519e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4520e5337592SStefano 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);
4521e5337592SStefano Zampini       }
4522e5337592SStefano Zampini #endif
4523e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 1;
4524e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 3;
4525e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4526e5337592SStefano Zampini #if 1
4527e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4528e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4529e5337592SStefano 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);
4530e5337592SStefano Zampini       }
4531e5337592SStefano Zampini #endif
4532e5337592SStefano Zampini       ++newp;
4533e5337592SStefano Zampini       /* Face {i, m, l, f} */
4534e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
4535e5337592SStefano Zampini       orntNew[0] = 0;
4536e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
4537e5337592SStefano Zampini       orntNew[1] = -2;
4538e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2);
4539e5337592SStefano Zampini       orntNew[2] = -2;
4540e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1);
4541e5337592SStefano Zampini       orntNew[3] = 0;
4542e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4543e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4544e5337592SStefano Zampini #if 1
4545e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4546e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4547e5337592SStefano 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);
4548e5337592SStefano Zampini       }
4549e5337592SStefano Zampini #endif
4550e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 2;
4551e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 3;
4552e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4553e5337592SStefano Zampini #if 1
4554e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4555e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4556e5337592SStefano 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);
4557e5337592SStefano Zampini       }
4558e5337592SStefano Zampini #endif
4559e5337592SStefano Zampini       ++newp;
4560e5337592SStefano Zampini     }
4561e5337592SStefano Zampini     /* Split Edges have 2 vertices and the same faces as the parent */
4562e5337592SStefano Zampini     for (e = eStart; e < eEnd; ++e) {
4563e5337592SStefano Zampini       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
4564e5337592SStefano Zampini 
4565e5337592SStefano Zampini       for (r = 0; r < 2; ++r) {
4566e5337592SStefano Zampini         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
4567e5337592SStefano Zampini         const PetscInt *cone, *ornt, *support;
4568e5337592SStefano Zampini         PetscInt        coneNew[2], coneSize, c, supportSize, s;
4569e5337592SStefano Zampini 
4570e5337592SStefano Zampini         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
4571e5337592SStefano Zampini         coneNew[0]       = vStartNew + (cone[0] - vStart);
4572e5337592SStefano Zampini         coneNew[1]       = vStartNew + (cone[1] - vStart);
4573e5337592SStefano Zampini         coneNew[(r+1)%2] = newv;
4574e5337592SStefano Zampini         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4575e5337592SStefano Zampini #if 1
4576e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4577e5337592SStefano Zampini         for (p = 0; p < 2; ++p) {
4578e5337592SStefano 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);
4579e5337592SStefano Zampini         }
4580e5337592SStefano Zampini #endif
4581e5337592SStefano Zampini         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
4582e5337592SStefano Zampini         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
4583e5337592SStefano Zampini         for (s = 0; s < supportSize; ++s) {
4584e5337592SStefano Zampini           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
4585e5337592SStefano Zampini           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4586e5337592SStefano Zampini           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
4587e5337592SStefano Zampini           for (c = 0; c < coneSize; ++c) {
4588e5337592SStefano Zampini             if (cone[c] == e) break;
4589e5337592SStefano Zampini           }
4590e5337592SStefano Zampini           supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3;
4591e5337592SStefano Zampini         }
4592e5337592SStefano Zampini         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4593e5337592SStefano Zampini #if 1
4594e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4595e5337592SStefano Zampini         for (p = 0; p < supportSize; ++p) {
4596e5337592SStefano 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);
4597e5337592SStefano Zampini         }
4598e5337592SStefano Zampini #endif
4599e5337592SStefano Zampini       }
4600e5337592SStefano Zampini     }
4601e5337592SStefano Zampini     /* Face edges have 2 vertices and 2 + cell faces supports */
4602e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
4603e5337592SStefano Zampini       const PetscInt *cone, *ornt, *support;
4604e5337592SStefano Zampini       PetscInt        coneSize, supportSize, s;
4605e5337592SStefano Zampini 
4606e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
4607e5337592SStefano Zampini       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
4608e5337592SStefano Zampini       for (r = 0; r < 3; ++r) {
4609e5337592SStefano Zampini         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
4610e5337592SStefano Zampini         PetscInt        coneNew[2];
4611e5337592SStefano Zampini         PetscInt        fint[4][3] = { {0, 1, 2},
4612e5337592SStefano Zampini                                        {3, 4, 0},
4613e5337592SStefano Zampini                                        {2, 5, 3},
4614e5337592SStefano Zampini                                        {1, 4, 5} };
4615e5337592SStefano Zampini 
4616e5337592SStefano Zampini         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
4617e5337592SStefano Zampini         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
4618e5337592SStefano Zampini         coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart;
4619e5337592SStefano Zampini         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4620e5337592SStefano Zampini #if 1
4621e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4622e5337592SStefano Zampini         for (p = 0; p < 2; ++p) {
4623e5337592SStefano 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);
4624e5337592SStefano Zampini         }
4625e5337592SStefano Zampini #endif
4626e5337592SStefano Zampini         supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3;
4627e5337592SStefano Zampini         supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3;
4628e5337592SStefano Zampini         for (s = 0; s < supportSize; ++s) {
4629e5337592SStefano Zampini           PetscInt er;
4630e5337592SStefano Zampini           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
4631e5337592SStefano Zampini           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4632e5337592SStefano Zampini           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
4633e5337592SStefano Zampini           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
4634e5337592SStefano Zampini           er = GetTriInteriorEdgeInverse_Static(ornt[c], r);
4635e5337592SStefano Zampini           supportRef[2+s] = fStartNew + (fEnd - fStart)*3 + (support[s] - cStart)*6 + fint[c][er];
4636e5337592SStefano Zampini         }
4637e5337592SStefano Zampini         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4638e5337592SStefano Zampini #if 1
4639e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4640e5337592SStefano Zampini         for (p = 0; p < supportSize + 2; ++p) {
4641e5337592SStefano 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);
4642e5337592SStefano Zampini         }
4643e5337592SStefano Zampini #endif
4644e5337592SStefano Zampini       }
4645e5337592SStefano Zampini     }
4646e5337592SStefano Zampini     /* Interior cell edges have 2 vertices and 3 faces */
4647e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
4648e5337592SStefano Zampini       const PetscInt *cone;
4649e5337592SStefano Zampini       PetscInt       fint[4][3] = { {0,1,2},
4650e5337592SStefano Zampini                                     {0,3,4},
4651e5337592SStefano Zampini                                     {2,3,5},
4652e5337592SStefano Zampini                                     {1,4,5} } ;
4653e5337592SStefano Zampini 
4654e5337592SStefano Zampini       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
4655e5337592SStefano Zampini       for (r = 0; r < 4; r++) {
4656e5337592SStefano Zampini         PetscInt       coneNew[2], supportNew[3];
4657e5337592SStefano Zampini         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r;
4658e5337592SStefano Zampini 
4659e5337592SStefano Zampini         coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
4660e5337592SStefano Zampini         coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd -fStart) + c - cStart;
4661e5337592SStefano Zampini         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4662e5337592SStefano Zampini #if 1
4663e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4664e5337592SStefano Zampini         for (p = 0; p < 2; ++p) {
4665e5337592SStefano 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);
4666e5337592SStefano Zampini         }
4667e5337592SStefano Zampini #endif
4668e5337592SStefano Zampini         supportNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][0];
4669e5337592SStefano Zampini         supportNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][1];
4670e5337592SStefano Zampini         supportNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][2];
4671e5337592SStefano Zampini         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4672e5337592SStefano Zampini #if 1
4673e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4674e5337592SStefano Zampini         for (p = 0; p < 3; ++p) {
4675e5337592SStefano 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);
4676e5337592SStefano Zampini         }
4677e5337592SStefano Zampini #endif
4678e5337592SStefano Zampini       }
4679e5337592SStefano Zampini     }
4680e5337592SStefano Zampini     /* Old vertices have identical supports */
4681e5337592SStefano Zampini     for (v = vStart; v < vEnd; ++v) {
4682e5337592SStefano Zampini       const PetscInt  newp = vStartNew + (v - vStart);
4683e5337592SStefano Zampini       const PetscInt *support, *cone;
4684e5337592SStefano Zampini       PetscInt        size, s;
4685e5337592SStefano Zampini 
4686e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
4687e5337592SStefano Zampini       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
4688e5337592SStefano Zampini       for (s = 0; s < size; ++s) {
4689e5337592SStefano Zampini         PetscInt r = 0;
4690e5337592SStefano Zampini 
4691e5337592SStefano Zampini         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4692e5337592SStefano Zampini         if (cone[1] == v) r = 1;
4693e5337592SStefano Zampini         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
4694e5337592SStefano Zampini       }
4695e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4696e5337592SStefano Zampini #if 1
4697e5337592SStefano Zampini       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
4698e5337592SStefano Zampini       for (p = 0; p < size; ++p) {
4699e5337592SStefano 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);
4700e5337592SStefano Zampini       }
4701e5337592SStefano Zampini #endif
4702e5337592SStefano Zampini     }
4703e5337592SStefano Zampini     /* Edge vertices have 2 + faces supports */
4704e5337592SStefano Zampini     for (e = eStart; e < eEnd; ++e) {
4705e5337592SStefano Zampini       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
4706e5337592SStefano Zampini       const PetscInt *cone, *support;
4707e5337592SStefano Zampini       PetscInt        size, s;
4708e5337592SStefano Zampini 
4709e5337592SStefano Zampini       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
4710e5337592SStefano Zampini       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
4711e5337592SStefano Zampini       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
4712e5337592SStefano Zampini       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
4713e5337592SStefano Zampini       for (s = 0; s < size; ++s) {
4714e5337592SStefano Zampini         PetscInt r = 0, coneSize;
4715e5337592SStefano Zampini 
4716e5337592SStefano Zampini         ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
4717e5337592SStefano Zampini         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4718e5337592SStefano Zampini         for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
4719e5337592SStefano Zampini         supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + r;
4720e5337592SStefano Zampini       }
4721e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4722e5337592SStefano Zampini #if 1
4723e5337592SStefano Zampini       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
4724e5337592SStefano Zampini       for (p = 0; p < 2+size; ++p) {
4725e5337592SStefano 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);
4726e5337592SStefano Zampini       }
4727e5337592SStefano Zampini #endif
4728e5337592SStefano Zampini     }
4729e5337592SStefano Zampini     /* Face vertices have 3 + cells supports */
4730e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
4731e5337592SStefano Zampini       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
4732e5337592SStefano Zampini       const PetscInt *cone, *support;
4733e5337592SStefano Zampini       PetscInt        size, s;
4734e5337592SStefano Zampini 
4735e5337592SStefano Zampini       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
4736e5337592SStefano Zampini       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
4737e5337592SStefano Zampini       supportRef[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0;
4738e5337592SStefano Zampini       supportRef[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1;
4739e5337592SStefano Zampini       supportRef[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2;
4740e5337592SStefano Zampini       for (s = 0; s < size; ++s) {
4741e5337592SStefano Zampini         PetscInt r = 0, coneSize;
4742e5337592SStefano Zampini 
4743e5337592SStefano Zampini         ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
4744e5337592SStefano Zampini         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4745e5337592SStefano Zampini         for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;}
4746e5337592SStefano Zampini         supportRef[3+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (support[s] - cStart)*4 + r;
4747e5337592SStefano Zampini       }
4748e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4749e5337592SStefano Zampini #if 1
4750e5337592SStefano Zampini       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
4751e5337592SStefano Zampini       for (p = 0; p < 3+size; ++p) {
4752e5337592SStefano 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);
4753e5337592SStefano Zampini       }
4754e5337592SStefano Zampini #endif
4755e5337592SStefano Zampini     }
4756e5337592SStefano Zampini     /* Interior cell vertices have 4 supports */
4757e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
4758e5337592SStefano Zampini       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + c - cStart;
4759e5337592SStefano Zampini       supportRef[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
4760e5337592SStefano Zampini       supportRef[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
4761e5337592SStefano Zampini       supportRef[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
4762e5337592SStefano Zampini       supportRef[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
4763e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4764e5337592SStefano Zampini #if 1
4765e5337592SStefano Zampini       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
4766e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4767e5337592SStefano 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);
4768e5337592SStefano Zampini       }
4769e5337592SStefano Zampini #endif
4770e5337592SStefano Zampini     }
4771e5337592SStefano Zampini     ierr = PetscFree(supportRef);CHKERRQ(ierr);
4772e5337592SStefano Zampini     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
4773e5337592SStefano Zampini     break;
47749b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
47752eabf88fSMatthew G. Knepley     /*
47762eabf88fSMatthew G. Knepley      Bottom (viewed from top)    Top
47772eabf88fSMatthew G. Knepley      1---------2---------2       7---------2---------6
47782eabf88fSMatthew G. Knepley      |         |         |       |         |         |
47792eabf88fSMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
47802eabf88fSMatthew G. Knepley      |         |         |       |         |         |
47812eabf88fSMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
47822eabf88fSMatthew G. Knepley      |         |         |       |         |         |
47832eabf88fSMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
47842eabf88fSMatthew G. Knepley      |         |         |       |         |         |
47852eabf88fSMatthew G. Knepley      0---------0---------3       4---------0---------5
47862eabf88fSMatthew G. Knepley      */
47872eabf88fSMatthew G. Knepley     /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
47882eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
47892eabf88fSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
47902eabf88fSMatthew G. Knepley       const PetscInt *cone, *ornt;
47912eabf88fSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
47922eabf88fSMatthew G. Knepley 
47932eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
47942eabf88fSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
47952eabf88fSMatthew G. Knepley       /* A hex */
4796e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
47972eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
47982eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
47992eabf88fSMatthew G. Knepley       orntNew[1] = 0;
4800e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
48012eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
48022eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
48032eabf88fSMatthew G. Knepley       orntNew[3] = 0;
48042eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
48052eabf88fSMatthew G. Knepley       orntNew[4] = 0;
4806e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
48072eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
48082eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
48092eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
48102eabf88fSMatthew G. Knepley #if 1
48112eabf88fSMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew);
48122eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
48132eabf88fSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
48142eabf88fSMatthew G. Knepley       }
48152eabf88fSMatthew G. Knepley #endif
48162eabf88fSMatthew G. Knepley       /* B hex */
4817e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
48182eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
48192eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
48202eabf88fSMatthew G. Knepley       orntNew[1] = 0;
48212eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
4822a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
4823e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
48242eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
48252eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
48262eabf88fSMatthew G. Knepley       orntNew[4] = 0;
4827e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
48282eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
48292eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
48302eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
48312eabf88fSMatthew G. Knepley #if 1
48322eabf88fSMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew);
48332eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
48342eabf88fSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
48352eabf88fSMatthew G. Knepley       }
48362eabf88fSMatthew G. Knepley #endif
48372eabf88fSMatthew G. Knepley       /* C hex */
4838e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
48392eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
48402eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
48412eabf88fSMatthew G. Knepley       orntNew[1] = 0;
48422eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
4843a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
4844e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
48452eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
4846e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
48472eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
48482eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
4849a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
48502eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
48512eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
48522eabf88fSMatthew G. Knepley #if 1
48532eabf88fSMatthew G. Knepley       if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew);
48542eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
48552eabf88fSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
48562eabf88fSMatthew G. Knepley       }
48572eabf88fSMatthew G. Knepley #endif
48582eabf88fSMatthew G. Knepley       /* D hex */
4859e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
48602eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
48612eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
48622eabf88fSMatthew G. Knepley       orntNew[1] = 0;
4863e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
48642eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
48652eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
4866a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4867e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
48682eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
48692eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
4870a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
48712eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
48722eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
48732eabf88fSMatthew G. Knepley #if 1
48742eabf88fSMatthew G. Knepley       if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew);
48752eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
48762eabf88fSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
48772eabf88fSMatthew G. Knepley       }
48782eabf88fSMatthew G. Knepley #endif
48792eabf88fSMatthew G. Knepley       /* E hex */
48802eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
4881a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
4882e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
48832eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
4884e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
48852eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
48862eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
48872eabf88fSMatthew G. Knepley       orntNew[3] = 0;
48882eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
4889a3cddbf8SMatthew G. Knepley       orntNew[4] = -1;
4890e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
48912eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
4892b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
4893b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
48942eabf88fSMatthew G. Knepley #if 1
4895b164cbf2SMatthew G. Knepley       if ((newp+4 < cStartNew) || (newp+4 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+4, cStartNew, cEndNew);
48962eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
48972eabf88fSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
48982eabf88fSMatthew G. Knepley       }
48992eabf88fSMatthew G. Knepley #endif
49002eabf88fSMatthew G. Knepley       /* F hex */
49012eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
4902a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
4903e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
49042eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
4905e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
49062eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
49072eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
4908a3cddbf8SMatthew G. Knepley       orntNew[3] = -1;
4909e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
49102eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
49112eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
4912a3cddbf8SMatthew G. Knepley       orntNew[5] = 1;
4913b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
4914b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
49152eabf88fSMatthew G. Knepley #if 1
4916b164cbf2SMatthew G. Knepley       if ((newp+5 < cStartNew) || (newp+5 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+5, cStartNew, cEndNew);
49172eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
49182eabf88fSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
49192eabf88fSMatthew G. Knepley       }
49202eabf88fSMatthew G. Knepley #endif
49212eabf88fSMatthew G. Knepley       /* G hex */
49222eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
4923a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
4924e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
49252eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
49262eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
4927a3cddbf8SMatthew G. Knepley       orntNew[2] = 0;
4928e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
49292eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
4930e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
49312eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
49322eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
4933a3cddbf8SMatthew G. Knepley       orntNew[5] = -3;
4934b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
4935b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
49362eabf88fSMatthew G. Knepley #if 1
4937b164cbf2SMatthew G. Knepley       if ((newp+6 < cStartNew) || (newp+6 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+6, cStartNew, cEndNew);
49382eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
49392eabf88fSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
49402eabf88fSMatthew G. Knepley       }
49412eabf88fSMatthew G. Knepley #endif
49422eabf88fSMatthew G. Knepley       /* H hex */
49432eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
4944a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
4945e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
49462eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
49472eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
4948a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
4949e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
49502eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
49512eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
4952a3cddbf8SMatthew G. Knepley       orntNew[4] = 3;
4953e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
49542eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
4955b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
4956b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
49572eabf88fSMatthew G. Knepley #if 1
4958b164cbf2SMatthew G. Knepley       if ((newp+7 < cStartNew) || (newp+7 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+7, cStartNew, cEndNew);
49592eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
49602eabf88fSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
49612eabf88fSMatthew G. Knepley       }
49622eabf88fSMatthew G. Knepley #endif
49632eabf88fSMatthew G. Knepley     }
49642eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
49652eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
4966854ce69bSBarry Smith     ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
49672eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
49682eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
4969aaebbb9dSMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
49702eabf88fSMatthew G. Knepley         const PetscInt  newCells[24] = {0, 1, 2, 3,  4, 5, 6, 7,  0, 3, 5, 4,  2, 1, 7, 6,  3, 2, 6, 5,  0, 4, 7, 1};
49712eabf88fSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
49722eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
4973aaebbb9dSMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
49742eabf88fSMatthew G. Knepley 
49752eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
4976aaebbb9dSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
4977a3cddbf8SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
4978a3cddbf8SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
4979a3cddbf8SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
4980a3cddbf8SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
4981a3cddbf8SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
4982a3cddbf8SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
4983a3cddbf8SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4;
4984a3cddbf8SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
49852eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4986aaebbb9dSMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
49872eabf88fSMatthew G. Knepley #if 1
49882eabf88fSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
49892eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
49902eabf88fSMatthew G. Knepley           if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
49912eabf88fSMatthew G. Knepley         }
49922eabf88fSMatthew G. Knepley #endif
49932eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
49942eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
49952eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
49962eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
49972eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
49982eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
49992eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
50002eabf88fSMatthew G. Knepley             if (cone[c] == f) break;
50012eabf88fSMatthew G. Knepley           }
5002a3cddbf8SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)];
50032eabf88fSMatthew G. Knepley         }
50042eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
50052eabf88fSMatthew G. Knepley #if 1
50062eabf88fSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
50072eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
50082eabf88fSMatthew G. Knepley           if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
50092eabf88fSMatthew G. Knepley         }
50102eabf88fSMatthew G. Knepley #endif
50112eabf88fSMatthew G. Knepley       }
50122eabf88fSMatthew G. Knepley     }
50132eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
50142eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
50152eabf88fSMatthew G. Knepley       const PetscInt  newCells[24] = {0, 3,  2, 3,  1, 2,  0, 1,  4, 5,  5, 6,  6, 7,  4, 7,  0, 4,  3, 5,  2, 6,  1, 7};
5016afb2665bSMatthew G. Knepley       const PetscInt *cone, *ornt;
5017afb2665bSMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
50182eabf88fSMatthew G. Knepley 
50192eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
5020afb2665bSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
5021afb2665bSMatthew G. Knepley       /* A-D face */
5022afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0;
5023a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
5024a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
5025a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
5026afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5027a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
5028a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
5029a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
5030afb2665bSMatthew G. Knepley       orntNew[3] = -2;
50312eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5032afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
50332eabf88fSMatthew G. Knepley #if 1
50342eabf88fSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
50352eabf88fSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
50362eabf88fSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
50372eabf88fSMatthew G. Knepley       }
50382eabf88fSMatthew G. Knepley #endif
5039afb2665bSMatthew G. Knepley       /* C-D face */
5040afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1;
5041a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
5042a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
5043a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
5044afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5045a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
5046a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
5047a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
5048afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5049afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5050afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5051afb2665bSMatthew G. Knepley #if 1
5052afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5053afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5054afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
5055afb2665bSMatthew G. Knepley       }
5056afb2665bSMatthew G. Knepley #endif
5057afb2665bSMatthew G. Knepley       /* B-C face */
5058afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2;
5059afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
5060afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5061afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
5062afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5063afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
5064afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5065afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
5066afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5067afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5068afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5069afb2665bSMatthew G. Knepley #if 1
5070afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5071afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5072afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
5073afb2665bSMatthew G. Knepley       }
5074afb2665bSMatthew G. Knepley #endif
5075afb2665bSMatthew G. Knepley       /* A-B face */
5076afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3;
5077afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
5078afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5079afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
5080afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5081afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
5082afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5083afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
5084afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5085afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5086afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5087afb2665bSMatthew G. Knepley #if 1
5088afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5089afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5090afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
5091afb2665bSMatthew G. Knepley       }
5092afb2665bSMatthew G. Knepley #endif
5093afb2665bSMatthew G. Knepley       /* E-F face */
5094afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4;
5095a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
5096afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5097a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
5098a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
5099a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
5100afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5101a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
5102a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
5103afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5104afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5105afb2665bSMatthew G. Knepley #if 1
5106afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5107afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5108afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
5109afb2665bSMatthew G. Knepley       }
5110afb2665bSMatthew G. Knepley #endif
5111afb2665bSMatthew G. Knepley       /* F-G face */
5112afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5;
5113a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
5114afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5115a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
5116a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
5117a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
5118afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5119a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
5120a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
5121afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5122afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5123afb2665bSMatthew G. Knepley #if 1
5124afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5125afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5126afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
5127afb2665bSMatthew G. Knepley       }
5128afb2665bSMatthew G. Knepley #endif
5129afb2665bSMatthew G. Knepley       /* G-H face */
5130afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6;
5131afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
5132afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5133afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
5134afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5135afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
5136afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5137afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
5138afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5139afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5140afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5141afb2665bSMatthew G. Knepley #if 1
5142afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5143afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5144afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
5145afb2665bSMatthew G. Knepley       }
5146afb2665bSMatthew G. Knepley #endif
5147afb2665bSMatthew G. Knepley       /* E-H face */
5148afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7;
5149a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
5150afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5151a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
5152a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
5153a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
5154afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5155a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
5156a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
5157afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5158afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5159afb2665bSMatthew G. Knepley #if 1
5160afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5161afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5162afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
5163afb2665bSMatthew G. Knepley       }
5164afb2665bSMatthew G. Knepley #endif
5165afb2665bSMatthew G. Knepley       /* A-E face */
5166afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8;
5167a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
5168a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
5169a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
5170afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5171a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
5172a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
5173a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
5174afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5175afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5176afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5177afb2665bSMatthew G. Knepley #if 1
5178afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5179afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5180afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
5181afb2665bSMatthew G. Knepley       }
5182afb2665bSMatthew G. Knepley #endif
5183afb2665bSMatthew G. Knepley       /* D-F face */
5184afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9;
5185afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
5186afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5187afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
5188afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5189afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
5190afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5191afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
5192afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5193afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5194afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5195afb2665bSMatthew G. Knepley #if 1
5196afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5197afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5198afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
5199afb2665bSMatthew G. Knepley       }
5200afb2665bSMatthew G. Knepley #endif
5201afb2665bSMatthew G. Knepley       /* C-G face */
5202afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10;
5203a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
5204afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5205a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
5206a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
5207a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
5208afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5209a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
5210a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
5211afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5212afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5213afb2665bSMatthew G. Knepley #if 1
5214afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5215afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5216afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
5217afb2665bSMatthew G. Knepley       }
5218afb2665bSMatthew G. Knepley #endif
5219afb2665bSMatthew G. Knepley       /* B-H face */
5220afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11;
5221a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
5222a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
5223a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
5224a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
5225a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
5226a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
5227a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
5228a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
5229afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5230afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5231afb2665bSMatthew G. Knepley #if 1
5232afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5233afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5234afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
5235afb2665bSMatthew G. Knepley       }
5236afb2665bSMatthew G. Knepley #endif
5237afb2665bSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
5238afb2665bSMatthew G. Knepley         newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
52392eabf88fSMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
52402eabf88fSMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
52412eabf88fSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
52422eabf88fSMatthew G. Knepley #if 1
52432eabf88fSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
52442eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
52452eabf88fSMatthew G. Knepley           if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
52462eabf88fSMatthew G. Knepley         }
52472eabf88fSMatthew G. Knepley #endif
52482eabf88fSMatthew G. Knepley       }
52492eabf88fSMatthew G. Knepley     }
52502eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
52512eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
52522eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
52532eabf88fSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
52542eabf88fSMatthew G. Knepley 
52552eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
52562eabf88fSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
52572eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
52582eabf88fSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
52592eabf88fSMatthew G. Knepley 
52602eabf88fSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
52612eabf88fSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
52622eabf88fSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
52632eabf88fSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
52642eabf88fSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
52652eabf88fSMatthew G. Knepley #if 1
52662eabf88fSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
52672eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
52682eabf88fSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
52692eabf88fSMatthew G. Knepley         }
52702eabf88fSMatthew G. Knepley #endif
52712eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
52722eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
52732eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
52742eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
52752eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
52762eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
52772eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
52782eabf88fSMatthew G. Knepley             if (cone[c] == e) break;
52792eabf88fSMatthew G. Knepley           }
52802eabf88fSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
52812eabf88fSMatthew G. Knepley         }
52822eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
52832eabf88fSMatthew G. Knepley #if 1
52842eabf88fSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
52852eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
52862eabf88fSMatthew G. Knepley           if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
52872eabf88fSMatthew G. Knepley         }
52882eabf88fSMatthew G. Knepley #endif
52892eabf88fSMatthew G. Knepley       }
52902eabf88fSMatthew G. Knepley     }
52912eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
52922eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
52936b852384SMatthew G. Knepley       const PetscInt  newFaces[24] = {3, 2, 1, 0,  4, 5, 6, 7,  0, 9, 4, 8,  2, 11, 6, 10,  1, 10, 5, 9,  8, 7, 11, 3};
52942eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
52956b852384SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
52962eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
52972eabf88fSMatthew G. Knepley 
52982eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
52992eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
53002eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
53012eabf88fSMatthew G. Knepley 
53022eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
53032eabf88fSMatthew G. Knepley         coneNew[1] = newv;
53042eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
53052eabf88fSMatthew G. Knepley #if 1
53062eabf88fSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
53072eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
53082eabf88fSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
53092eabf88fSMatthew G. Knepley         }
53102eabf88fSMatthew G. Knepley #endif
53112eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
53122eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
53132eabf88fSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
53142eabf88fSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
53152eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
53166b852384SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
53176b852384SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
53186b852384SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
53192eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
5320a3cddbf8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
53212eabf88fSMatthew G. Knepley         }
53222eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
53232eabf88fSMatthew G. Knepley #if 1
53242eabf88fSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
53252eabf88fSMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
53262eabf88fSMatthew G. Knepley           if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
53272eabf88fSMatthew G. Knepley         }
53282eabf88fSMatthew G. Knepley #endif
53292eabf88fSMatthew G. Knepley       }
53302eabf88fSMatthew G. Knepley     }
53312eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
53322eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
53332eabf88fSMatthew G. Knepley       const PetscInt  newFaces[24] = {0, 1, 2, 3,  4, 5, 6, 7,  0, 9, 4, 8,  2, 11, 6, 10,  1, 10, 5, 9,  3, 8, 7, 11};
53342eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
53352eabf88fSMatthew G. Knepley       const PetscInt *cone;
53362eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
53372eabf88fSMatthew G. Knepley 
53382eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
53392eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
53402eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
53412eabf88fSMatthew G. Knepley 
53422eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
53432eabf88fSMatthew G. Knepley         coneNew[1] = newv;
53442eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
53452eabf88fSMatthew G. Knepley #if 1
53462eabf88fSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
53472eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
53482eabf88fSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
53492eabf88fSMatthew G. Knepley         }
53502eabf88fSMatthew G. Knepley #endif
53512eabf88fSMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
53522eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
53532eabf88fSMatthew G. Knepley #if 1
53542eabf88fSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
53552eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
53562eabf88fSMatthew G. Knepley           if ((supportNew[p] < fStartNew) || (supportNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportNew[p], fStartNew, fEndNew);
53572eabf88fSMatthew G. Knepley         }
53582eabf88fSMatthew G. Knepley #endif
53592eabf88fSMatthew G. Knepley       }
53602eabf88fSMatthew G. Knepley     }
53612eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
53622eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
53632eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
53642eabf88fSMatthew G. Knepley       const PetscInt *support, *cone;
53652eabf88fSMatthew G. Knepley       PetscInt        size, s;
53662eabf88fSMatthew G. Knepley 
53672eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
53682eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
53692eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
53702eabf88fSMatthew G. Knepley         PetscInt r = 0;
53712eabf88fSMatthew G. Knepley 
53722eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
53732eabf88fSMatthew G. Knepley         if (cone[1] == v) r = 1;
53742eabf88fSMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
53752eabf88fSMatthew G. Knepley       }
53762eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
53772eabf88fSMatthew G. Knepley #if 1
53782eabf88fSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
53792eabf88fSMatthew G. Knepley       for (p = 0; p < size; ++p) {
53802eabf88fSMatthew G. Knepley         if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
53812eabf88fSMatthew G. Knepley       }
53822eabf88fSMatthew G. Knepley #endif
53832eabf88fSMatthew G. Knepley     }
53842eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
53852eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
53862eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
53872eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
53882eabf88fSMatthew G. Knepley       PetscInt        size, s;
53892eabf88fSMatthew G. Knepley 
53902eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
53912eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
53922eabf88fSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
53932eabf88fSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
53942eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
53952eabf88fSMatthew G. Knepley         PetscInt r;
53962eabf88fSMatthew G. Knepley 
53972eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
5398a660e16cSMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
53992eabf88fSMatthew G. Knepley         supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r;
54002eabf88fSMatthew G. Knepley       }
54012eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
54022eabf88fSMatthew G. Knepley #if 1
54032eabf88fSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
54042eabf88fSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
54052eabf88fSMatthew G. Knepley         if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
54062eabf88fSMatthew G. Knepley       }
54072eabf88fSMatthew G. Knepley #endif
54082eabf88fSMatthew G. Knepley     }
54092eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
54102eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
54112eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
54122eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
54132eabf88fSMatthew G. Knepley       PetscInt        size, s;
54142eabf88fSMatthew G. Knepley 
54152eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
54162eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
54170793999aSMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 +  (f - fStart)*4 + r;
54182eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
54192eabf88fSMatthew G. Knepley         PetscInt r;
54202eabf88fSMatthew G. Knepley 
54212eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
54222eabf88fSMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
54232eabf88fSMatthew G. Knepley         supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r;
54242eabf88fSMatthew G. Knepley       }
54252eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
54262eabf88fSMatthew G. Knepley #if 1
54272eabf88fSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
54282eabf88fSMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
54292eabf88fSMatthew G. Knepley         if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
54302eabf88fSMatthew G. Knepley       }
54312eabf88fSMatthew G. Knepley #endif
54322eabf88fSMatthew G. Knepley     }
54332eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
54342eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
54352eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
54362eabf88fSMatthew G. Knepley       PetscInt       supportNew[6];
54372eabf88fSMatthew G. Knepley 
54382eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
54392eabf88fSMatthew G. Knepley         supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
54402eabf88fSMatthew G. Knepley       }
54412eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
54422eabf88fSMatthew G. Knepley     }
5443da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
54442eabf88fSMatthew G. Knepley     break;
54459b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
544627fcede3SMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
544727fcede3SMatthew G. Knepley     /*
544827fcede3SMatthew G. Knepley      Bottom (viewed from top)    Top
544927fcede3SMatthew G. Knepley      1---------2---------2       7---------2---------6
545027fcede3SMatthew G. Knepley      |         |         |       |         |         |
545127fcede3SMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
545227fcede3SMatthew G. Knepley      |         |         |       |         |         |
545327fcede3SMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
545427fcede3SMatthew G. Knepley      |         |         |       |         |         |
545527fcede3SMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
545627fcede3SMatthew G. Knepley      |         |         |       |         |         |
545727fcede3SMatthew G. Knepley      0---------0---------3       4---------0---------5
545827fcede3SMatthew G. Knepley      */
545927fcede3SMatthew G. Knepley     /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
546027fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
546127fcede3SMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
546227fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
546327fcede3SMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
546427fcede3SMatthew G. Knepley 
546527fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
546627fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
546727fcede3SMatthew G. Knepley       /* A hex */
546827fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
546927fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
547027fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
547127fcede3SMatthew G. Knepley       orntNew[1] = 0;
547227fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
547327fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
547427fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
547527fcede3SMatthew G. Knepley       orntNew[3] = 0;
547627fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
547727fcede3SMatthew G. Knepley       orntNew[4] = 0;
547827fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
547927fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
548027fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
548127fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
548227fcede3SMatthew G. Knepley #if 1
548327fcede3SMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cMaxNew);
548427fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
548527fcede3SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
548627fcede3SMatthew G. Knepley       }
548727fcede3SMatthew G. Knepley #endif
548827fcede3SMatthew G. Knepley       /* B hex */
548927fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
549027fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
549127fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
549227fcede3SMatthew G. Knepley       orntNew[1] = 0;
549327fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
549427fcede3SMatthew G. Knepley       orntNew[2] = -1;
549527fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
549627fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
549727fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
549827fcede3SMatthew G. Knepley       orntNew[4] = 0;
549927fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
550027fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
550127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
550227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
550327fcede3SMatthew G. Knepley #if 1
550427fcede3SMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cMaxNew);
550527fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
550627fcede3SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
550727fcede3SMatthew G. Knepley       }
550827fcede3SMatthew G. Knepley #endif
550927fcede3SMatthew G. Knepley       /* C hex */
551027fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
551127fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
551227fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
551327fcede3SMatthew G. Knepley       orntNew[1] = 0;
551427fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
551527fcede3SMatthew G. Knepley       orntNew[2] = -1;
551627fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
551727fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
551827fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
551927fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
552027fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
552127fcede3SMatthew G. Knepley       orntNew[5] = -4;
552227fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
552327fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
552427fcede3SMatthew G. Knepley #if 1
552527fcede3SMatthew G. Knepley       if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cMaxNew);
552627fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
552727fcede3SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
552827fcede3SMatthew G. Knepley       }
552927fcede3SMatthew G. Knepley #endif
553027fcede3SMatthew G. Knepley       /* D hex */
553127fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
553227fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
553327fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
553427fcede3SMatthew G. Knepley       orntNew[1] = 0;
553527fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
553627fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
553727fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
553827fcede3SMatthew G. Knepley       orntNew[3] = 0;
553927fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
554027fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
554127fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
554227fcede3SMatthew G. Knepley       orntNew[5] = -4;
554327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
554427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
554527fcede3SMatthew G. Knepley #if 1
554627fcede3SMatthew G. Knepley       if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cMaxNew);
554727fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
554827fcede3SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
554927fcede3SMatthew G. Knepley       }
555027fcede3SMatthew G. Knepley #endif
555127fcede3SMatthew G. Knepley       /* E hex */
555227fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
555327fcede3SMatthew G. Knepley       orntNew[0] = -4;
555427fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
555527fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
555627fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
555727fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
555827fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
555927fcede3SMatthew G. Knepley       orntNew[3] = 0;
556027fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
556127fcede3SMatthew G. Knepley       orntNew[4] = -1;
556227fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
556327fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
556427fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
556527fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
556627fcede3SMatthew G. Knepley #if 1
556727fcede3SMatthew G. Knepley       if ((newp+4 < cStartNew) || (newp+4 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+4, cStartNew, cMaxNew);
556827fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
556927fcede3SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
557027fcede3SMatthew G. Knepley       }
557127fcede3SMatthew G. Knepley #endif
557227fcede3SMatthew G. Knepley       /* F hex */
557327fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
557427fcede3SMatthew G. Knepley       orntNew[0] = -4;
557527fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
557627fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
557727fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
557827fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
557927fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
558027fcede3SMatthew G. Knepley       orntNew[3] = -1;
558127fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
558227fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
558327fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
558427fcede3SMatthew G. Knepley       orntNew[5] = 1;
558527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
558627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
558727fcede3SMatthew G. Knepley #if 1
558827fcede3SMatthew G. Knepley       if ((newp+5 < cStartNew) || (newp+5 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+5, cStartNew, cMaxNew);
558927fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
559027fcede3SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
559127fcede3SMatthew G. Knepley       }
559227fcede3SMatthew G. Knepley #endif
559327fcede3SMatthew G. Knepley       /* G hex */
559427fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
559527fcede3SMatthew G. Knepley       orntNew[0] = -4;
559627fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
559727fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
559827fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
559927fcede3SMatthew G. Knepley       orntNew[2] = 0;
560027fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
560127fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
560227fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
560327fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
560427fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
560527fcede3SMatthew G. Knepley       orntNew[5] = -3;
560627fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
560727fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
560827fcede3SMatthew G. Knepley #if 1
560927fcede3SMatthew G. Knepley       if ((newp+6 < cStartNew) || (newp+6 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+6, cStartNew, cMaxNew);
561027fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
561127fcede3SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
561227fcede3SMatthew G. Knepley       }
561327fcede3SMatthew G. Knepley #endif
561427fcede3SMatthew G. Knepley       /* H hex */
561527fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
561627fcede3SMatthew G. Knepley       orntNew[0] = -4;
561727fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
561827fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
561927fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
562027fcede3SMatthew G. Knepley       orntNew[2] = -1;
562127fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
562227fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
562327fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
562427fcede3SMatthew G. Knepley       orntNew[4] = 3;
562527fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
562627fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
562727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
562827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
562927fcede3SMatthew G. Knepley #if 1
563027fcede3SMatthew G. Knepley       if ((newp+7 < cStartNew) || (newp+7 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+7, cStartNew, cMaxNew);
563127fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
563227fcede3SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
563327fcede3SMatthew G. Knepley       }
563427fcede3SMatthew G. Knepley #endif
563527fcede3SMatthew G. Knepley     }
563627fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces: Front, Back, Sides */
563727fcede3SMatthew G. Knepley     /*
563827fcede3SMatthew G. Knepley      3---------2---------2
563927fcede3SMatthew G. Knepley      |         |         |
564027fcede3SMatthew G. Knepley      |    D    2    C    |
564127fcede3SMatthew G. Knepley      |         |         |
564227fcede3SMatthew G. Knepley      3----3----0----1----1
564327fcede3SMatthew G. Knepley      |         |         |
564427fcede3SMatthew G. Knepley      |    A    0    B    |
564527fcede3SMatthew G. Knepley      |         |         |
564627fcede3SMatthew G. Knepley      0---------0---------1
564727fcede3SMatthew G. Knepley      */
564827fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
564927fcede3SMatthew G. Knepley       const PetscInt  newp = (cMax - cStart)*8 + (c - cMax)*4;
565027fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
5651d273725eSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6], o, of, i;
565227fcede3SMatthew G. Knepley 
565327fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
565427fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
565527fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
5656d273725eSMatthew G. Knepley       o = ornt[0] < 0 ? -1 : 1;
565727fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
565827fcede3SMatthew G. Knepley         PetscInt subfA = GetQuadSubface_Static(ornt[0], r);
565927fcede3SMatthew G. Knepley         PetscInt edgeA = GetQuadEdge_Static(ornt[0], r);
5660d273725eSMatthew G. Knepley         PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4);
566127fcede3SMatthew G. Knepley         if (ornt[0] != ornt[1]) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent ordering for matching ends of hybrid cell %d: %d != %d", c, ornt[0], ornt[1]);
566227fcede3SMatthew G. Knepley         coneNew[0]         = fStartNew + (cone[0] - fStart)*4 + subfA;
566327fcede3SMatthew G. Knepley         orntNew[0]         = ornt[0];
566427fcede3SMatthew G. Knepley         coneNew[1]         = fStartNew + (cone[1] - fStart)*4 + subfA;
566527fcede3SMatthew G. Knepley         orntNew[1]         = ornt[0];
5666d273725eSMatthew G. Knepley         of = fornt[edgeA] < 0 ? -1 : 1;
5667d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], r) + 2;
5668d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0);
5669d273725eSMatthew G. Knepley         orntNew[i] = ornt[edgeA];
5670d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2;
5671d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeA;
5672d273725eSMatthew G. Knepley         orntNew[i] = 0;
5673d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2;
5674d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeB;
5675d273725eSMatthew G. Knepley         orntNew[i] = -2;
5676d273725eSMatthew G. Knepley         of = fornt[edgeB] < 0 ? -1 : 1;
5677d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2;
5678d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1);
5679d273725eSMatthew G. Knepley         orntNew[i] = ornt[edgeB];
568027fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
568127fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
568227fcede3SMatthew G. Knepley #if 1
568327fcede3SMatthew G. Knepley         if ((newp+r < cMaxNew) || (newp+r >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", newp+r, cMaxNew, cEndNew);
568427fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
568527fcede3SMatthew G. Knepley           if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
568627fcede3SMatthew G. Knepley         }
568727fcede3SMatthew G. Knepley         for (p = 2; p < 6; ++p) {
568827fcede3SMatthew G. Knepley           if ((coneNew[p] < fMaxNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", coneNew[p], fMaxNew, fEndNew);
568927fcede3SMatthew G. Knepley         }
569027fcede3SMatthew G. Knepley #endif
569127fcede3SMatthew G. Knepley       }
569227fcede3SMatthew G. Knepley     }
569327fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
569427fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
5695854ce69bSBarry Smith     ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
569627fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
569727fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
569827fcede3SMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
569927fcede3SMatthew G. Knepley         const PetscInt  newCells[24] = {0, 1, 2, 3,  4, 5, 6, 7,  0, 3, 5, 4,  2, 1, 7, 6,  3, 2, 6, 5,  0, 4, 7, 1};
570027fcede3SMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
570127fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
570227fcede3SMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
570327fcede3SMatthew G. Knepley 
570427fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
570527fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
570627fcede3SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
570727fcede3SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
570827fcede3SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
570927fcede3SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
571027fcede3SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
571127fcede3SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
571227fcede3SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4;
571327fcede3SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
571427fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
571527fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
571627fcede3SMatthew G. Knepley #if 1
571727fcede3SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
571827fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
571927fcede3SMatthew G. Knepley           if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
572027fcede3SMatthew G. Knepley         }
572127fcede3SMatthew G. Knepley #endif
572227fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
572327fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
572427fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
572527fcede3SMatthew G. Knepley           PetscInt subf;
572627fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
572727fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
572827fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
572927fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
573027fcede3SMatthew G. Knepley             if (cone[c] == f) break;
573127fcede3SMatthew G. Knepley           }
573227fcede3SMatthew G. Knepley           subf = GetQuadSubfaceInverse_Static(ornt[c], r);
573327fcede3SMatthew G. Knepley           if (support[s] < cMax) {
573427fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf];
573527fcede3SMatthew G. Knepley           } else {
573627fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax       - cStart)*8 + (support[s] - cMax)*4 + subf;
573727fcede3SMatthew G. Knepley           }
573827fcede3SMatthew G. Knepley         }
573927fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
574027fcede3SMatthew G. Knepley #if 1
574127fcede3SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
574227fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
574327fcede3SMatthew G. Knepley           if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
574427fcede3SMatthew G. Knepley         }
574527fcede3SMatthew G. Knepley #endif
574627fcede3SMatthew G. Knepley       }
574727fcede3SMatthew G. Knepley     }
5748d273725eSMatthew G. Knepley     /* Interior cell faces have 4 edges and 2 cells */
574927fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
575027fcede3SMatthew G. Knepley       const PetscInt  newCells[24] = {0, 3,  2, 3,  1, 2,  0, 1,  4, 5,  5, 6,  6, 7,  4, 7,  0, 4,  3, 5,  2, 6,  1, 7};
575127fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
575227fcede3SMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
575327fcede3SMatthew G. Knepley 
575427fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
575527fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
575627fcede3SMatthew G. Knepley       /* A-D face */
575727fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0;
575827fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
575927fcede3SMatthew G. Knepley       orntNew[0] = 0;
576027fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
576127fcede3SMatthew G. Knepley       orntNew[1] = 0;
576227fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
576327fcede3SMatthew G. Knepley       orntNew[2] = -2;
576427fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
576527fcede3SMatthew G. Knepley       orntNew[3] = -2;
576627fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
576727fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
576827fcede3SMatthew G. Knepley #if 1
576927fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
577027fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
577127fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
577227fcede3SMatthew G. Knepley       }
577327fcede3SMatthew G. Knepley #endif
577427fcede3SMatthew G. Knepley       /* C-D face */
577527fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1;
577627fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
577727fcede3SMatthew G. Knepley       orntNew[0] = 0;
577827fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
577927fcede3SMatthew G. Knepley       orntNew[1] = 0;
578027fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
578127fcede3SMatthew G. Knepley       orntNew[2] = -2;
578227fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
578327fcede3SMatthew G. Knepley       orntNew[3] = -2;
578427fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
578527fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
578627fcede3SMatthew G. Knepley #if 1
578727fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
578827fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
578927fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
579027fcede3SMatthew G. Knepley       }
579127fcede3SMatthew G. Knepley #endif
579227fcede3SMatthew G. Knepley       /* B-C face */
579327fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2;
579427fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
579527fcede3SMatthew G. Knepley       orntNew[0] = -2;
579627fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
579727fcede3SMatthew G. Knepley       orntNew[1] = 0;
579827fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
579927fcede3SMatthew G. Knepley       orntNew[2] = 0;
580027fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
580127fcede3SMatthew G. Knepley       orntNew[3] = -2;
580227fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
580327fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
580427fcede3SMatthew G. Knepley #if 1
580527fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
580627fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
580727fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
580827fcede3SMatthew G. Knepley       }
580927fcede3SMatthew G. Knepley #endif
581027fcede3SMatthew G. Knepley       /* A-B face */
581127fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3;
581227fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
581327fcede3SMatthew G. Knepley       orntNew[0] = -2;
581427fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
581527fcede3SMatthew G. Knepley       orntNew[1] = 0;
581627fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
581727fcede3SMatthew G. Knepley       orntNew[2] = 0;
581827fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
581927fcede3SMatthew G. Knepley       orntNew[3] = -2;
582027fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
582127fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
582227fcede3SMatthew G. Knepley #if 1
582327fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
582427fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
582527fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
582627fcede3SMatthew G. Knepley       }
582727fcede3SMatthew G. Knepley #endif
582827fcede3SMatthew G. Knepley       /* E-F face */
582927fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4;
583027fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
583127fcede3SMatthew G. Knepley       orntNew[0] = -2;
583227fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
583327fcede3SMatthew G. Knepley       orntNew[1] = -2;
583427fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
583527fcede3SMatthew G. Knepley       orntNew[2] = 0;
583627fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
583727fcede3SMatthew G. Knepley       orntNew[3] = 0;
583827fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
583927fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
584027fcede3SMatthew G. Knepley #if 1
584127fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
584227fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
584327fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
584427fcede3SMatthew G. Knepley       }
584527fcede3SMatthew G. Knepley #endif
584627fcede3SMatthew G. Knepley       /* F-G face */
584727fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5;
584827fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
584927fcede3SMatthew G. Knepley       orntNew[0] = -2;
585027fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
585127fcede3SMatthew G. Knepley       orntNew[1] = -2;
585227fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
585327fcede3SMatthew G. Knepley       orntNew[2] = 0;
585427fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
585527fcede3SMatthew G. Knepley       orntNew[3] = 0;
585627fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
585727fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
585827fcede3SMatthew G. Knepley #if 1
585927fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
586027fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
586127fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
586227fcede3SMatthew G. Knepley       }
586327fcede3SMatthew G. Knepley #endif
586427fcede3SMatthew G. Knepley       /* G-H face */
586527fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6;
586627fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
586727fcede3SMatthew G. Knepley       orntNew[0] = -2;
586827fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
586927fcede3SMatthew G. Knepley       orntNew[1] = 0;
587027fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
587127fcede3SMatthew G. Knepley       orntNew[2] = 0;
587227fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
587327fcede3SMatthew G. Knepley       orntNew[3] = -2;
587427fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
587527fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
587627fcede3SMatthew G. Knepley #if 1
587727fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
587827fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
587927fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
588027fcede3SMatthew G. Knepley       }
588127fcede3SMatthew G. Knepley #endif
588227fcede3SMatthew G. Knepley       /* E-H face */
588327fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7;
588427fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
588527fcede3SMatthew G. Knepley       orntNew[0] = -2;
588627fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
588727fcede3SMatthew G. Knepley       orntNew[1] = -2;
588827fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
588927fcede3SMatthew G. Knepley       orntNew[2] = 0;
589027fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
589127fcede3SMatthew G. Knepley       orntNew[3] = 0;
589227fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
589327fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
589427fcede3SMatthew G. Knepley #if 1
589527fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
589627fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
589727fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
589827fcede3SMatthew G. Knepley       }
589927fcede3SMatthew G. Knepley #endif
590027fcede3SMatthew G. Knepley       /* A-E face */
590127fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8;
590227fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
590327fcede3SMatthew G. Knepley       orntNew[0] = 0;
590427fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
590527fcede3SMatthew G. Knepley       orntNew[1] = 0;
590627fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
590727fcede3SMatthew G. Knepley       orntNew[2] = -2;
590827fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
590927fcede3SMatthew G. Knepley       orntNew[3] = -2;
591027fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
591127fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
591227fcede3SMatthew G. Knepley #if 1
591327fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
591427fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
591527fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
591627fcede3SMatthew G. Knepley       }
591727fcede3SMatthew G. Knepley #endif
591827fcede3SMatthew G. Knepley       /* D-F face */
591927fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9;
592027fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
592127fcede3SMatthew G. Knepley       orntNew[0] = -2;
592227fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
592327fcede3SMatthew G. Knepley       orntNew[1] = 0;
592427fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
592527fcede3SMatthew G. Knepley       orntNew[2] = 0;
592627fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
592727fcede3SMatthew G. Knepley       orntNew[3] = -2;
592827fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
592927fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
593027fcede3SMatthew G. Knepley #if 1
593127fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
593227fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
593327fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
593427fcede3SMatthew G. Knepley       }
593527fcede3SMatthew G. Knepley #endif
593627fcede3SMatthew G. Knepley       /* C-G face */
593727fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10;
593827fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
593927fcede3SMatthew G. Knepley       orntNew[0] = -2;
594027fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
594127fcede3SMatthew G. Knepley       orntNew[1] = -2;
594227fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
594327fcede3SMatthew G. Knepley       orntNew[2] = 0;
594427fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
594527fcede3SMatthew G. Knepley       orntNew[3] = 0;
594627fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
594727fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
594827fcede3SMatthew G. Knepley #if 1
594927fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
595027fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
595127fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
595227fcede3SMatthew G. Knepley       }
595327fcede3SMatthew G. Knepley #endif
595427fcede3SMatthew G. Knepley       /* B-H face */
595527fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11;
595627fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
595727fcede3SMatthew G. Knepley       orntNew[0] = 0;
595827fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
595927fcede3SMatthew G. Knepley       orntNew[1] = -2;
596027fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
596127fcede3SMatthew G. Knepley       orntNew[2] = -2;
596227fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
596327fcede3SMatthew G. Knepley       orntNew[3] = 0;
596427fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
596527fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
596627fcede3SMatthew G. Knepley #if 1
596727fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
596827fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
596927fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
597027fcede3SMatthew G. Knepley       }
597127fcede3SMatthew G. Knepley #endif
597227fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
597327fcede3SMatthew G. Knepley         newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
597427fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
597527fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
597627fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
597727fcede3SMatthew G. Knepley #if 1
597827fcede3SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
597927fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
598027fcede3SMatthew G. Knepley           if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
598127fcede3SMatthew G. Knepley         }
598227fcede3SMatthew G. Knepley #endif
598327fcede3SMatthew G. Knepley       }
598427fcede3SMatthew G. Knepley     }
598527fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
598627fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
598727fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
598827fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
598927fcede3SMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
599027fcede3SMatthew G. Knepley 
599127fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
599227fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
599327fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
599427fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
599527fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
599627fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
599727fcede3SMatthew G. Knepley 
599827fcede3SMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
599927fcede3SMatthew G. Knepley         orntNew[0]   = ornt[0];
600027fcede3SMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
600127fcede3SMatthew G. Knepley         orntNew[1]   = ornt[1];
600227fcede3SMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax);
600327fcede3SMatthew G. Knepley         orntNew[2+r] = 0;
600427fcede3SMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd      - eMax) + (f - fMax);
600527fcede3SMatthew G. Knepley         orntNew[3-r] = 0;
600627fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
600727fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
600827fcede3SMatthew G. Knepley #if 1
600927fcede3SMatthew G. Knepley         if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew);
601027fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
601127fcede3SMatthew G. Knepley           if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
601227fcede3SMatthew G. Knepley         }
601327fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
601427fcede3SMatthew G. Knepley           if ((coneNew[p] < eMaxNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", coneNew[p], eMaxNew, eEndNew);
601527fcede3SMatthew G. Knepley         }
601627fcede3SMatthew G. Knepley #endif
601727fcede3SMatthew G. Knepley         for (s = 0; s < size; ++s) {
601827fcede3SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
6019d273725eSMatthew G. Knepley           PetscInt        o, of;
602027fcede3SMatthew G. Knepley 
602127fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
602227fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
6023d273725eSMatthew G. Knepley           o = orntCell[0] < 0 ? -1 : 1;
602427fcede3SMatthew G. Knepley           for (c = 2; c < 6; ++c) if (coneCell[c] == f) break;
602527fcede3SMatthew G. Knepley           if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]);
602627fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
6027d273725eSMatthew G. Knepley           of = fornt[c-2] < 0 ? -1 : 1;
6028d273725eSMatthew G. Knepley           supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%4;
602927fcede3SMatthew G. Knepley         }
603027fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
603127fcede3SMatthew G. Knepley #if 1
603227fcede3SMatthew G. Knepley         if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew);
603327fcede3SMatthew G. Knepley         for (p = 0; p < size; ++p) {
603427fcede3SMatthew G. Knepley           if ((supportNew[p] < cMaxNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", supportNew[p], cMaxNew, cEndNew);
603527fcede3SMatthew G. Knepley         }
603627fcede3SMatthew G. Knepley #endif
603727fcede3SMatthew G. Knepley       }
603827fcede3SMatthew G. Knepley     }
603927fcede3SMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
604027fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
604127fcede3SMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4;
604227fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
604327fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
604427fcede3SMatthew G. Knepley       PetscInt        supportNew[2];
604527fcede3SMatthew G. Knepley 
604627fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
604727fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
604827fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
6049d273725eSMatthew G. Knepley #if 0
605027fcede3SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r);
605127fcede3SMatthew G. Knepley         orntNew[0] = 0;
605227fcede3SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r);
605327fcede3SMatthew G. Knepley         orntNew[1] = 0;
605427fcede3SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax);
605527fcede3SMatthew G. Knepley         orntNew[2] = 0;
605627fcede3SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd                                   - fMax) + (c - cMax);
605727fcede3SMatthew G. Knepley         orntNew[3] = 0;
6058d273725eSMatthew G. Knepley #else
6059d273725eSMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r;
6060d273725eSMatthew G. Knepley         orntNew[0] = 0;
6061d273725eSMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r;
6062d273725eSMatthew G. Knepley         orntNew[1] = 0;
6063d273725eSMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax);
6064d273725eSMatthew G. Knepley         orntNew[2] = 0;
6065d273725eSMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd      - fMax) + (c - cMax);
6066d273725eSMatthew G. Knepley         orntNew[3] = 0;
6067d273725eSMatthew G. Knepley #endif
606827fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
606927fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
607027fcede3SMatthew G. Knepley #if 1
607127fcede3SMatthew G. Knepley         if ((newp+r < fMaxNew) || (newp+r >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp+r, fMaxNew, fEndNew);
607227fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
607327fcede3SMatthew G. Knepley           if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
607427fcede3SMatthew G. Knepley         }
607527fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
607627fcede3SMatthew G. Knepley           if ((coneNew[p] < eMaxNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", coneNew[p], eMaxNew, eEndNew);
607727fcede3SMatthew G. Knepley         }
607827fcede3SMatthew G. Knepley #endif
607927fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r);
608027fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4);
608127fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
608227fcede3SMatthew G. Knepley #if 1
608327fcede3SMatthew G. Knepley         if ((newp+r < fMaxNew) || (newp+r >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp+r, fMaxNew, fEndNew);
608427fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
608527fcede3SMatthew G. Knepley           if ((supportNew[p] < cMaxNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", supportNew[p], cMaxNew, cEndNew);
608627fcede3SMatthew G. Knepley         }
608727fcede3SMatthew G. Knepley #endif
608827fcede3SMatthew G. Knepley       }
608927fcede3SMatthew G. Knepley     }
609027fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
609127fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
609227fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
609327fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
609427fcede3SMatthew G. Knepley 
609527fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
609627fcede3SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
609727fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
609827fcede3SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
609927fcede3SMatthew G. Knepley 
610027fcede3SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
610127fcede3SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
610227fcede3SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
610327fcede3SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
610427fcede3SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
610527fcede3SMatthew G. Knepley #if 1
610627fcede3SMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
610727fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
610827fcede3SMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
610927fcede3SMatthew G. Knepley         }
611027fcede3SMatthew G. Knepley #endif
611127fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
611227fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
611327fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
611427fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
611527fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
611627fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
611727fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
611827fcede3SMatthew G. Knepley             if (cone[c] == e) break;
611927fcede3SMatthew G. Knepley           }
612027fcede3SMatthew G. Knepley           if (support[s] < fMax) {
612127fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4;
612227fcede3SMatthew G. Knepley           } else {
612327fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
612427fcede3SMatthew G. Knepley           }
612527fcede3SMatthew G. Knepley         }
612627fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
612727fcede3SMatthew G. Knepley #if 1
612827fcede3SMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
612927fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
613027fcede3SMatthew G. Knepley           if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
613127fcede3SMatthew G. Knepley         }
613227fcede3SMatthew G. Knepley #endif
613327fcede3SMatthew G. Knepley       }
613427fcede3SMatthew G. Knepley     }
613527fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
613627fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
613727fcede3SMatthew G. Knepley       const PetscInt  newFaces[24] = {3, 2, 1, 0,  4, 5, 6, 7,  0, 9, 4, 8,  2, 11, 6, 10,  1, 10, 5, 9,  8, 7, 11, 3};
613827fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
613927fcede3SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
614027fcede3SMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
614127fcede3SMatthew G. Knepley 
614227fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
614327fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
614427fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
614527fcede3SMatthew G. Knepley 
614627fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
614727fcede3SMatthew G. Knepley         coneNew[1] = newv;
614827fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
614927fcede3SMatthew G. Knepley #if 1
615027fcede3SMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
615127fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
615227fcede3SMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
615327fcede3SMatthew G. Knepley         }
615427fcede3SMatthew G. Knepley #endif
615527fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
615627fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
615727fcede3SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
615827fcede3SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
615927fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
616027fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
616127fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
616227fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
616327fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
616427fcede3SMatthew G. Knepley           if (support[s] < cMax) {
616527fcede3SMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
616627fcede3SMatthew G. Knepley           } else {
6167d273725eSMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r;
616827fcede3SMatthew G. Knepley           }
616927fcede3SMatthew G. Knepley         }
617027fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
617127fcede3SMatthew G. Knepley #if 1
617227fcede3SMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
617327fcede3SMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
617427fcede3SMatthew G. Knepley           if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
617527fcede3SMatthew G. Knepley         }
617627fcede3SMatthew G. Knepley #endif
617727fcede3SMatthew G. Knepley       }
617827fcede3SMatthew G. Knepley     }
617927fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
618027fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
618127fcede3SMatthew G. Knepley       const PetscInt  newFaces[24] = {0, 1, 2, 3,  4, 5, 6, 7,  0, 9, 4, 8,  2, 11, 6, 10,  1, 10, 5, 9,  3, 8, 7, 11};
618227fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
618327fcede3SMatthew G. Knepley       const PetscInt *cone;
618427fcede3SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
618527fcede3SMatthew G. Knepley 
618627fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
618727fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
618827fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
618927fcede3SMatthew G. Knepley 
619027fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart);
619127fcede3SMatthew G. Knepley         coneNew[1] = newv;
619227fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
619327fcede3SMatthew G. Knepley #if 1
619427fcede3SMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
619527fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
619627fcede3SMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
619727fcede3SMatthew G. Knepley         }
619827fcede3SMatthew G. Knepley #endif
619927fcede3SMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
620027fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
620127fcede3SMatthew G. Knepley #if 1
620227fcede3SMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
620327fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
620427fcede3SMatthew G. Knepley           if ((supportNew[p] < fStartNew) || (supportNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportNew[p], fStartNew, fMaxNew);
620527fcede3SMatthew G. Knepley         }
620627fcede3SMatthew G. Knepley #endif
620727fcede3SMatthew G. Knepley       }
620827fcede3SMatthew G. Knepley     }
620927fcede3SMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
621027fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
621127fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
621227fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
621327fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
621427fcede3SMatthew G. Knepley 
621527fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
621627fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
621727fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
621827fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
621927fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
622027fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
622127fcede3SMatthew G. Knepley #if 1
622227fcede3SMatthew G. Knepley       if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
622327fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
622427fcede3SMatthew G. Knepley         if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
622527fcede3SMatthew G. Knepley       }
622627fcede3SMatthew G. Knepley #endif
622727fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
622827fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
622927fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
623027fcede3SMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
623127fcede3SMatthew G. Knepley         if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]);
623227fcede3SMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2;
623327fcede3SMatthew G. Knepley       }
623427fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
623527fcede3SMatthew G. Knepley #if 1
623627fcede3SMatthew G. Knepley       if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
623727fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
623827fcede3SMatthew G. Knepley         if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", supportRef[p], fMaxNew, fEndNew);
623927fcede3SMatthew G. Knepley       }
624027fcede3SMatthew G. Knepley #endif
624127fcede3SMatthew G. Knepley     }
624227fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
624327fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
624427fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
624527fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
624627fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
624727fcede3SMatthew G. Knepley 
624827fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
624927fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
625027fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
625127fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
625227fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
625327fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
625427fcede3SMatthew G. Knepley #if 1
625527fcede3SMatthew G. Knepley       if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
625627fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
625727fcede3SMatthew G. Knepley         if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
625827fcede3SMatthew G. Knepley       }
625927fcede3SMatthew G. Knepley #endif
626027fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0;
626127fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1;
626227fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
626327fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
626427fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
626527fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
626627fcede3SMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
626727fcede3SMatthew G. Knepley         if ((c < 2) || (c >= csize)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Hybrid face %d is not in cone of hybrid cell %d", f, support[s]);
6268d273725eSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2;
626927fcede3SMatthew G. Knepley       }
627027fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
627127fcede3SMatthew G. Knepley #if 1
627227fcede3SMatthew G. Knepley       if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
627327fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
627427fcede3SMatthew G. Knepley         if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", supportRef[p], fMaxNew, fEndNew);
627527fcede3SMatthew G. Knepley       }
627627fcede3SMatthew G. Knepley #endif
627727fcede3SMatthew G. Knepley     }
627827fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
627927fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
628027fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
628127fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
628227fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size;
628327fcede3SMatthew G. Knepley 
628427fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
628527fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr);
628627fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr);
628727fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart);
628827fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart);
628927fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
629027fcede3SMatthew G. Knepley #if 1
629127fcede3SMatthew G. Knepley       if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
629227fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
629327fcede3SMatthew G. Knepley         if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
629427fcede3SMatthew G. Knepley       }
629527fcede3SMatthew G. Knepley #endif
629627fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0;
629727fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1;
629827fcede3SMatthew G. Knepley       supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2;
629927fcede3SMatthew G. Knepley       supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3;
630027fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
630127fcede3SMatthew G. Knepley #if 1
630227fcede3SMatthew G. Knepley       if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
630327fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
630427fcede3SMatthew G. Knepley         if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", supportRef[p], fMaxNew, fEndNew);
630527fcede3SMatthew G. Knepley       }
630627fcede3SMatthew G. Knepley #endif
630727fcede3SMatthew G. Knepley     }
630827fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
630927fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
631027fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
631127fcede3SMatthew G. Knepley       const PetscInt *support, *cone;
631227fcede3SMatthew G. Knepley       PetscInt        size, s;
631327fcede3SMatthew G. Knepley 
631427fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
631527fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
631627fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
631727fcede3SMatthew G. Knepley         PetscInt r = 0;
631827fcede3SMatthew G. Knepley 
631927fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
632027fcede3SMatthew G. Knepley         if (cone[1] == v) r = 1;
632127fcede3SMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
632227fcede3SMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax);
632327fcede3SMatthew G. Knepley       }
632427fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
632527fcede3SMatthew G. Knepley #if 1
632627fcede3SMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
632727fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
632827fcede3SMatthew G. Knepley         if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
632927fcede3SMatthew G. Knepley       }
633027fcede3SMatthew G. Knepley #endif
633127fcede3SMatthew G. Knepley     }
633227fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
633327fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
633427fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
633527fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
633627fcede3SMatthew G. Knepley       PetscInt        size, s;
633727fcede3SMatthew G. Knepley 
633827fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
633927fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
634027fcede3SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
634127fcede3SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
634227fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
634327fcede3SMatthew G. Knepley         PetscInt r;
634427fcede3SMatthew G. Knepley 
634527fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
634627fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
634727fcede3SMatthew G. Knepley         if (support[s] < fMax) {
634827fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r;
634927fcede3SMatthew G. Knepley         } else {
635027fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax);
635127fcede3SMatthew G. Knepley         }
635227fcede3SMatthew G. Knepley       }
635327fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
635427fcede3SMatthew G. Knepley #if 1
635527fcede3SMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
635627fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
635727fcede3SMatthew G. Knepley         if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
635827fcede3SMatthew G. Knepley       }
635927fcede3SMatthew G. Knepley #endif
636027fcede3SMatthew G. Knepley     }
636127fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
636227fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
636327fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
636427fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
636527fcede3SMatthew G. Knepley       PetscInt        size, s;
636627fcede3SMatthew G. Knepley 
636727fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
636827fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
636927fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 +  (f - fStart)*4 + r;
637027fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
637127fcede3SMatthew G. Knepley         PetscInt r;
637227fcede3SMatthew G. Knepley 
637327fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
637427fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
637527fcede3SMatthew G. Knepley         if (support[s] < cMax) {
637627fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r;
637727fcede3SMatthew G. Knepley         } else {
637827fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax       - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax);
637927fcede3SMatthew G. Knepley         }
638027fcede3SMatthew G. Knepley       }
638127fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
638227fcede3SMatthew G. Knepley #if 1
638327fcede3SMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
638427fcede3SMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
638527fcede3SMatthew G. Knepley         if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
638627fcede3SMatthew G. Knepley       }
638727fcede3SMatthew G. Knepley #endif
638827fcede3SMatthew G. Knepley     }
638927fcede3SMatthew G. Knepley     /* Cell vertices have 6 supports */
639027fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
639127fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
639227fcede3SMatthew G. Knepley       PetscInt       supportNew[6];
639327fcede3SMatthew G. Knepley 
639427fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
639527fcede3SMatthew G. Knepley         supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
639627fcede3SMatthew G. Knepley       }
639727fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
639827fcede3SMatthew G. Knepley     }
639927fcede3SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
640027fcede3SMatthew G. Knepley     break;
640175d3a19aSMatthew G. Knepley   default:
640275d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
640375d3a19aSMatthew G. Knepley   }
640475d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
640575d3a19aSMatthew G. Knepley }
640675d3a19aSMatthew G. Knepley 
640786150812SJed Brown static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
640875d3a19aSMatthew G. Knepley {
640975d3a19aSMatthew G. Knepley   PetscSection          coordSection, coordSectionNew;
641075d3a19aSMatthew G. Knepley   Vec                   coordinates, coordinatesNew;
641175d3a19aSMatthew G. Knepley   PetscScalar          *coords, *coordsNew;
64123478d7aaSMatthew G. Knepley   const PetscInt        numVertices = depthSize ? depthSize[0] : 0;
641390b157c4SStefano Zampini   PetscInt              dim, spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax;
641490b157c4SStefano Zampini   PetscInt              c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f;
64159fc2a3f3SStefano Zampini   PetscInt              cStartNew, cEndNew, vEndNew, *parentId = NULL;
64168b9ced59SLisandro Dalcin   VecType               vtype;
64179fc2a3f3SStefano Zampini   PetscBool             isperiodic, localize = PETSC_FALSE, needcoords = PETSC_FALSE;
641890b157c4SStefano Zampini   const PetscReal      *maxCell, *L;
641990b157c4SStefano Zampini   const DMBoundaryType *bd;
642075d3a19aSMatthew G. Knepley   PetscErrorCode        ierr;
642175d3a19aSMatthew G. Knepley 
642275d3a19aSMatthew G. Knepley   PetscFunctionBegin;
6423a57030b0SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
642475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
642575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
6426b5da9499SMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
642775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
642875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
642927fcede3SMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr);
643090b157c4SStefano Zampini   ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, NULL, NULL, &vStartNew);CHKERRQ(ierr);
643190b157c4SStefano Zampini   ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, NULL, NULL, &vEndNew);CHKERRQ(ierr);
6432f719d809SMatthew G. Knepley   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
6433f1d7821bSLawrence Mitchell   ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr);
643475d3a19aSMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr);
643575d3a19aSMatthew G. Knepley   ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr);
6436f1d7821bSLawrence Mitchell   ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr);
643790b157c4SStefano Zampini   ierr = DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);CHKERRQ(ierr);
643890b157c4SStefano Zampini   ierr = DMSetPeriodicity(rdm, isperiodic,  maxCell,  L,  bd);CHKERRQ(ierr);
643990b157c4SStefano Zampini   /* Determine if we need to localize coordinates when generating them */
64409fc2a3f3SStefano Zampini   if (isperiodic && !maxCell) {
64419fc2a3f3SStefano Zampini     ierr = DMGetCoordinatesLocalized(dm, &localize);CHKERRQ(ierr);
64429fc2a3f3SStefano Zampini     if (!localize) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot refine if coordinates have not been localized");
64439fc2a3f3SStefano Zampini   }
644490b157c4SStefano Zampini   if (localize) {
644590b157c4SStefano Zampini     PetscInt p, r, newp, *pi;
644690b157c4SStefano Zampini 
644790b157c4SStefano Zampini     /* New coordinates will be already localized on the cell */
644890b157c4SStefano Zampini     ierr = PetscSectionSetChart(coordSectionNew, 0, vStartNew+numVertices);CHKERRQ(ierr);
644990b157c4SStefano Zampini 
645090b157c4SStefano Zampini     /* We need the parentId to properly localize coordinates */
645190b157c4SStefano Zampini     ierr = PetscMalloc1(cEndNew-cStartNew,&pi);CHKERRQ(ierr);
645290b157c4SStefano Zampini     switch (refiner) {
645390b157c4SStefano Zampini     case REFINER_NOOP:
645490b157c4SStefano Zampini       break;
645590b157c4SStefano Zampini     case REFINER_SIMPLEX_1D:
645690b157c4SStefano Zampini       for (p = cStart; p < cEnd; ++p) {
645790b157c4SStefano Zampini         for (r = 0; r < 2; ++r) {
645890b157c4SStefano Zampini           newp     = (p - cStart)*2 + r;
645990b157c4SStefano Zampini           pi[newp] = p;
646090b157c4SStefano Zampini         }
646190b157c4SStefano Zampini       }
646290b157c4SStefano Zampini       break;
646390b157c4SStefano Zampini     case REFINER_SIMPLEX_2D:
646490b157c4SStefano Zampini       for (p = cStart; p < cEnd; ++p) {
646590b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
646690b157c4SStefano Zampini           newp     = (p - cStart)*4 + r;
646790b157c4SStefano Zampini           pi[newp] = p;
646890b157c4SStefano Zampini         }
646990b157c4SStefano Zampini       }
647090b157c4SStefano Zampini       break;
647190b157c4SStefano Zampini     case REFINER_HEX_2D:
647290b157c4SStefano Zampini       for (p = cStart; p < cEnd; ++p) {
647390b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
647490b157c4SStefano Zampini           newp     = (p - cStart)*4 + r;
647590b157c4SStefano Zampini           pi[newp] = p;
647690b157c4SStefano Zampini         }
647790b157c4SStefano Zampini       }
647890b157c4SStefano Zampini       break;
647990b157c4SStefano Zampini     case REFINER_HYBRID_SIMPLEX_2D:
648090b157c4SStefano Zampini       for (p = cStart; p < cMax; ++p) {
648190b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
648290b157c4SStefano Zampini           newp     = (p - cStart)*4 + r;
648390b157c4SStefano Zampini           pi[newp] = p;
648490b157c4SStefano Zampini         }
648590b157c4SStefano Zampini       }
648690b157c4SStefano Zampini       for (p = cMax; p < cEnd; ++p) {
648790b157c4SStefano Zampini         for (r = 0; r < 2; ++r) {
648890b157c4SStefano Zampini           newp     = (cMax - cStart)*4 + (p - cMax)*2 + r;
648990b157c4SStefano Zampini           pi[newp] = p;
649090b157c4SStefano Zampini         }
649190b157c4SStefano Zampini       }
649290b157c4SStefano Zampini       break;
649390b157c4SStefano Zampini     case REFINER_HYBRID_HEX_2D:
649490b157c4SStefano Zampini       for (p = cStart; p < cMax; ++p) {
649590b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
649690b157c4SStefano Zampini           newp     = (p - cStart)*4 + r;
649790b157c4SStefano Zampini           pi[newp] = p;
649890b157c4SStefano Zampini         }
649990b157c4SStefano Zampini       }
650090b157c4SStefano Zampini       for (p = cMax; p < cEnd; ++p) {
650190b157c4SStefano Zampini         for (r = 0; r < 2; ++r) {
650290b157c4SStefano Zampini           newp     = (cMax - cStart)*4 + (p - cMax)*2 + r;
650390b157c4SStefano Zampini           pi[newp] = p;
650490b157c4SStefano Zampini         }
650590b157c4SStefano Zampini       }
650690b157c4SStefano Zampini       break;
650790b157c4SStefano Zampini     case REFINER_SIMPLEX_3D:
650890b157c4SStefano Zampini       for (p = cStart; p < cEnd; ++p) {
650990b157c4SStefano Zampini         for (r = 0; r < 8; ++r) {
651090b157c4SStefano Zampini           newp     = (p - cStart)*8 + r;
651190b157c4SStefano Zampini           pi[newp] = p;
651290b157c4SStefano Zampini         }
651390b157c4SStefano Zampini       }
651490b157c4SStefano Zampini       break;
651590b157c4SStefano Zampini     case REFINER_HYBRID_SIMPLEX_3D:
651690b157c4SStefano Zampini       for (p = cStart; p < cMax; ++p) {
651790b157c4SStefano Zampini         for (r = 0; r < 8; ++r) {
651890b157c4SStefano Zampini           newp     = (p - cStart)*8 + r;
651990b157c4SStefano Zampini           pi[newp] = p;
652090b157c4SStefano Zampini         }
652190b157c4SStefano Zampini       }
652290b157c4SStefano Zampini       for (p = cMax; p < cEnd; ++p) {
652390b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
652490b157c4SStefano Zampini           newp     = (cMax - cStart)*8 + (p - cMax)*4 + r;
652590b157c4SStefano Zampini           pi[newp] = p;
652690b157c4SStefano Zampini         }
652790b157c4SStefano Zampini       }
652890b157c4SStefano Zampini       break;
652990b157c4SStefano Zampini     case REFINER_HEX_3D:
653090b157c4SStefano Zampini       for (p = cStart; p < cEnd; ++p) {
653190b157c4SStefano Zampini         for (r = 0; r < 8; ++r) {
653290b157c4SStefano Zampini           newp = (p - cStart)*8 + r;
653390b157c4SStefano Zampini           pi[newp] = p;
653490b157c4SStefano Zampini         }
653590b157c4SStefano Zampini       }
653690b157c4SStefano Zampini       break;
653790b157c4SStefano Zampini     case REFINER_HYBRID_HEX_3D:
653890b157c4SStefano Zampini       for (p = cStart; p < cMax; ++p) {
653990b157c4SStefano Zampini         for (r = 0; r < 8; ++r) {
654090b157c4SStefano Zampini           newp = (p - cStart)*8 + r;
654190b157c4SStefano Zampini           pi[newp] = p;
654290b157c4SStefano Zampini         }
654390b157c4SStefano Zampini       }
654490b157c4SStefano Zampini       for (p = cMax; p < cEnd; ++p) {
654590b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
654690b157c4SStefano Zampini           newp = (cMax - cStart)*8 + (p - cMax)*4 + r;
6547*451a39c7SStefano Zampini           pi[newp] = p;
654890b157c4SStefano Zampini         }
654990b157c4SStefano Zampini       }
655090b157c4SStefano Zampini       break;
655190b157c4SStefano Zampini     default:
655290b157c4SStefano Zampini       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
655390b157c4SStefano Zampini     }
655490b157c4SStefano Zampini     parentId = pi;
655590b157c4SStefano Zampini   } else {
65563478d7aaSMatthew G. Knepley     ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr);
655790b157c4SStefano Zampini   }
655827fcede3SMatthew G. Knepley   if (cMax < 0) cMax = cEnd;
655975d3a19aSMatthew G. Knepley   if (fMax < 0) fMax = fEnd;
6560b5da9499SMatthew G. Knepley   if (eMax < 0) eMax = eEnd;
656190b157c4SStefano Zampini 
6562f1d7821bSLawrence Mitchell   /* All vertices have the spaceDim coordinates */
656390b157c4SStefano Zampini   if (localize) {
65649fc2a3f3SStefano Zampini     PetscInt c;
656590b157c4SStefano Zampini 
65669fc2a3f3SStefano Zampini     for (c = cStartNew; c < cEndNew; ++c) {
65679fc2a3f3SStefano Zampini       PetscInt *cone = NULL;
65689fc2a3f3SStefano Zampini       PetscInt  closureSize, coneSize = 0, p, pdof;
65699fc2a3f3SStefano Zampini 
65709fc2a3f3SStefano Zampini       ierr = PetscSectionGetDof(coordSection, parentId[c], &pdof); CHKERRQ(ierr);
65719fc2a3f3SStefano Zampini       if (pdof) { /* localize on all cells that are refinement of a localized parent cell */
65729fc2a3f3SStefano Zampini         ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
657390b157c4SStefano Zampini         for (p = 0; p < closureSize*2; p += 2) {
657490b157c4SStefano Zampini           const PetscInt point = cone[p];
657590b157c4SStefano Zampini           if ((point >= vStartNew) && (point < vEndNew)) coneSize++;
657690b157c4SStefano Zampini         }
65779fc2a3f3SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
65789fc2a3f3SStefano Zampini         ierr = PetscSectionSetDof(coordSectionNew, c, coneSize*spaceDim);CHKERRQ(ierr);
65799fc2a3f3SStefano Zampini         ierr = PetscSectionSetFieldDof(coordSectionNew, c, 0, coneSize*spaceDim);CHKERRQ(ierr);
65809fc2a3f3SStefano Zampini       }
658190b157c4SStefano Zampini     }
658290b157c4SStefano Zampini   }
65833478d7aaSMatthew G. Knepley   for (v = vStartNew; v < vStartNew+numVertices; ++v) {
6584f1d7821bSLawrence Mitchell     ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr);
6585f1d7821bSLawrence Mitchell     ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr);
658675d3a19aSMatthew G. Knepley   }
658775d3a19aSMatthew G. Knepley   ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr);
658846e270d4SMatthew G. Knepley   ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr);
658975d3a19aSMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
659075d3a19aSMatthew G. Knepley   ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr);
65918b9ced59SLisandro Dalcin   ierr = VecCreate(PETSC_COMM_SELF, &coordinatesNew);CHKERRQ(ierr);
659275d3a19aSMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr);
659375d3a19aSMatthew G. Knepley   ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr);
659460b9e8a1SMatthew G. Knepley   ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr);
659560b9e8a1SMatthew G. Knepley   ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr);
65968b9ced59SLisandro Dalcin   ierr = VecGetType(coordinates, &vtype);CHKERRQ(ierr);
65978b9ced59SLisandro Dalcin   ierr = VecSetType(coordinatesNew, vtype);CHKERRQ(ierr);
659875d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr);
659975d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
66009fc2a3f3SStefano Zampini 
6601b5da9499SMatthew G. Knepley   switch (refiner) {
66029b1a0e7fSLawrence Mitchell   case REFINER_NOOP: break;
6603e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_3D:
66049b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
66059b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
6606b5da9499SMatthew G. Knepley     /* Face vertices have the average of corner coordinates */
6607d856d60fSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
660827fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
6609b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
6610b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
6611b5da9499SMatthew G. Knepley 
6612b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
6613b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
6614b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
6615b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
6616b5da9499SMatthew G. Knepley       }
661790b157c4SStefano Zampini       if (localize) {
661890b157c4SStefano Zampini         const PetscInt *support = NULL;
661990b157c4SStefano Zampini         PetscInt       *rStar = NULL;
662090b157c4SStefano Zampini         PetscInt        supportSize, rStarSize, coff, s, ccoff[8];
662190b157c4SStefano Zampini         PetscBool       cellfound = PETSC_FALSE;
662290b157c4SStefano Zampini 
662390b157c4SStefano Zampini         ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
662490b157c4SStefano Zampini         ierr = DMPlexGetSupportSize(dm,f,&supportSize);CHKERRQ(ierr);
662590b157c4SStefano Zampini         ierr = DMPlexGetSupport(dm,f,&support);CHKERRQ(ierr);
662690b157c4SStefano Zampini         /* Compute average of coordinates for each cell sharing the face */
662790b157c4SStefano Zampini         for (s = 0; s < supportSize; ++s) {
662890b157c4SStefano Zampini           PetscScalar     coordsNewAux[3] = { 0.0, 0.0, 0.0 };
662990b157c4SStefano Zampini           PetscInt       *cellCone = NULL;
66309fc2a3f3SStefano Zampini           PetscInt        cellClosureSize, cellConeSize = 0, cdof;
663190b157c4SStefano Zampini           const PetscInt  cell = support[s];
663290b157c4SStefano Zampini           PetscBool       copyoff = PETSC_FALSE;
663390b157c4SStefano Zampini 
663490b157c4SStefano Zampini           ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr);
663590b157c4SStefano Zampini           for (p = 0; p < cellClosureSize*2; p += 2) {
663690b157c4SStefano Zampini             const PetscInt point = cellCone[p];
663790b157c4SStefano Zampini             if ((point >= vStart) && (point < vEnd)) cellCone[cellConeSize++] = point;
663890b157c4SStefano Zampini           }
66399fc2a3f3SStefano Zampini           ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr);
66409fc2a3f3SStefano Zampini           if (!cdof) { /* the parent cell does not have localized coordinates */
66419fc2a3f3SStefano Zampini             cellfound = PETSC_TRUE;
66429fc2a3f3SStefano Zampini             for (v = 0; v < coneSize; ++v) {
66439fc2a3f3SStefano Zampini               ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
66449fc2a3f3SStefano Zampini               for (d = 0; d < spaceDim; ++d) coordsNewAux[d] += coords[off[v]+d];
66459fc2a3f3SStefano Zampini             }
66469fc2a3f3SStefano Zampini             for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize;
66479fc2a3f3SStefano Zampini           } else {
66489fc2a3f3SStefano Zampini             ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr);
664990b157c4SStefano Zampini             for (p = 0; p < coneSize; ++p) {
665090b157c4SStefano Zampini               const PetscInt tv = cone[p];
665190b157c4SStefano Zampini               PetscInt       cv, voff;
665290b157c4SStefano Zampini               PetscBool      locv = PETSC_TRUE;
665390b157c4SStefano Zampini 
665490b157c4SStefano Zampini               for (cv = 0; cv < cellConeSize; ++cv) {
665590b157c4SStefano Zampini                 if (cellCone[cv] == tv) {
665690b157c4SStefano Zampini                   ccoff[p] = spaceDim*cv + coff;
665790b157c4SStefano Zampini                   break;
665890b157c4SStefano Zampini                 }
665990b157c4SStefano Zampini               }
666090b157c4SStefano Zampini               if (cv == cellConeSize) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map vertex %D\n",tv);
666190b157c4SStefano Zampini 
666290b157c4SStefano Zampini               ierr = PetscSectionGetOffset(coordSection, cone[p], &voff);CHKERRQ(ierr);
666390b157c4SStefano Zampini               for (d = 0; d < spaceDim; ++d) {
666490b157c4SStefano Zampini                 coordsNewAux[d] += coords[ccoff[p]+d];
666590b157c4SStefano Zampini                 if (!cellfound && coords[voff+d] != coords[ccoff[p]+d]) locv = PETSC_FALSE;
666690b157c4SStefano Zampini               }
666790b157c4SStefano Zampini               if (locv && !cellfound) {
666890b157c4SStefano Zampini                 cellfound = PETSC_TRUE;
666990b157c4SStefano Zampini                 copyoff   = PETSC_TRUE;
667090b157c4SStefano Zampini               }
667190b157c4SStefano Zampini             }
66729fc2a3f3SStefano Zampini             for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize;
667390b157c4SStefano Zampini 
667490b157c4SStefano Zampini             /* Found a valid face for the "vertex" part of the Section (physical space)
667590b157c4SStefano Zampini                i.e., a face that has at least one corner in the physical space */
667690b157c4SStefano Zampini             if (copyoff) for (p = 0; p < coneSize; ++p) off[p] = ccoff[p];
66779fc2a3f3SStefano Zampini           }
667890b157c4SStefano Zampini 
667990b157c4SStefano Zampini           /* Localize new coordinates on each refined cell */
668090b157c4SStefano Zampini           for (v = 0; v < rStarSize*2; v += 2) {
668190b157c4SStefano Zampini             if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew) && parentId[rStar[v]-cStartNew] == cell) {
66829fc2a3f3SStefano Zampini               PetscInt       *rcone = NULL, rclosureSize, lid, rcdof, rcoff;
668390b157c4SStefano Zampini               const PetscInt  rcell = rStar[v];
668490b157c4SStefano Zampini 
66859fc2a3f3SStefano Zampini               ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr);
66869fc2a3f3SStefano Zampini               if (!rcdof) continue;
66879fc2a3f3SStefano Zampini               ierr = PetscSectionGetOffset(coordSectionNew, rcell, &rcoff);CHKERRQ(ierr);
668890b157c4SStefano Zampini               ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr);
668990b157c4SStefano Zampini               for (p = 0, lid = 0; p < rclosureSize*2; p += 2) {
669090b157c4SStefano Zampini                 if (rcone[p] == newv) {
66919fc2a3f3SStefano Zampini                   for (d = 0; d < spaceDim; d++) coordsNew[rcoff + lid*spaceDim + d] = coordsNewAux[d];
669290b157c4SStefano Zampini                   break;
669390b157c4SStefano Zampini                 }
669490b157c4SStefano Zampini                 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++;
669590b157c4SStefano Zampini               }
669690b157c4SStefano Zampini               ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr);
669790b157c4SStefano Zampini               if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv);
669890b157c4SStefano Zampini             }
669990b157c4SStefano Zampini           }
67009fc2a3f3SStefano Zampini           ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr);
670190b157c4SStefano Zampini         }
670290b157c4SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
670390b157c4SStefano Zampini         if (!cellfound) {
67041072f78bSStefano Zampini           /* Could not find a valid face for the vertex part, we will get this vertex later (final reduction) */
67051072f78bSStefano Zampini           needcoords = PETSC_TRUE;
670690b157c4SStefano Zampini           coneSize   = 0;
670790b157c4SStefano Zampini         }
670890b157c4SStefano Zampini       } else {
6709b5da9499SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) {
6710b5da9499SMatthew G. Knepley           ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
6711b5da9499SMatthew G. Knepley         }
671290b157c4SStefano Zampini       }
6713b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
671490b157c4SStefano Zampini       if (coneSize) {
67151072f78bSStefano Zampini         for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
67162e17dfb7SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);}
6717f1d7821bSLawrence Mitchell         for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
67181072f78bSStefano Zampini       } else {
67191072f78bSStefano Zampini         for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL;
672090b157c4SStefano Zampini       }
6721b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
6722b5da9499SMatthew G. Knepley     }
6723e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_2D:
67249b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
67259b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
6726383c10e6SMatthew G. Knepley   case REFINER_SIMPLEX_1D:
6727b5da9499SMatthew G. Knepley     /* Cell vertices have the average of corner coordinates */
672827fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
67292ed5862eSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (dim > 1 ? (eMax - eStart) : 0) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0);
6730b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
67319fc2a3f3SStefano Zampini       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d, cdof = 0;
6732b5da9499SMatthew G. Knepley 
6733b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
6734b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
6735b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
6736b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
6737b5da9499SMatthew G. Knepley       }
673890b157c4SStefano Zampini       if (localize) {
67399fc2a3f3SStefano Zampini         ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr);
67409fc2a3f3SStefano Zampini       }
67419fc2a3f3SStefano Zampini       if (cdof) {
674290b157c4SStefano Zampini         PetscInt coff;
674390b157c4SStefano Zampini 
674490b157c4SStefano Zampini         ierr = PetscSectionGetOffset(coordSection, c, &coff);CHKERRQ(ierr);
674590b157c4SStefano Zampini         for (v = 0; v < coneSize; ++v) off[v] = spaceDim*v + coff;
674690b157c4SStefano Zampini       } else {
6747b5da9499SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) {
6748b5da9499SMatthew G. Knepley           ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
6749b5da9499SMatthew G. Knepley         }
675090b157c4SStefano Zampini       }
6751b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
6752f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
67532e17dfb7SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);}
6754f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
6755b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
67569fc2a3f3SStefano Zampini 
675790b157c4SStefano Zampini       /* Localize new coordinates on each refined cell */
67589fc2a3f3SStefano Zampini       if (cdof) {
675990b157c4SStefano Zampini         PetscInt *rStar = NULL, rStarSize;
676090b157c4SStefano Zampini 
676190b157c4SStefano Zampini         ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
676290b157c4SStefano Zampini         for (v = 0; v < rStarSize*2; v += 2) {
676390b157c4SStefano Zampini           if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew)) {
67649fc2a3f3SStefano Zampini             PetscInt *cone = NULL, closureSize, lid, coff, rc, rcdof;
676590b157c4SStefano Zampini 
676690b157c4SStefano Zampini             rc   = rStar[v];
67679fc2a3f3SStefano Zampini             ierr = PetscSectionGetDof(coordSectionNew, rc, &rcdof);CHKERRQ(ierr);
67689fc2a3f3SStefano Zampini             if (!rcdof) continue;
676990b157c4SStefano Zampini             ierr = PetscSectionGetOffset(coordSectionNew, rc, &coff);CHKERRQ(ierr);
677090b157c4SStefano Zampini             ierr = DMPlexGetTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
677190b157c4SStefano Zampini             for (p = 0, lid = 0; p < closureSize*2; p += 2) {
677290b157c4SStefano Zampini               if (cone[p] == newv) {
677390b157c4SStefano Zampini                 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNew[offnew + d];
677490b157c4SStefano Zampini                 break;
677590b157c4SStefano Zampini               }
677690b157c4SStefano Zampini               if (cone[p] >= vStartNew && cone[p] < vEndNew) lid++;
677790b157c4SStefano Zampini             }
677890b157c4SStefano Zampini             if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv);
677990b157c4SStefano Zampini             ierr = DMPlexRestoreTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
678090b157c4SStefano Zampini           }
678190b157c4SStefano Zampini         }
678290b157c4SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
678390b157c4SStefano Zampini       }
6784b5da9499SMatthew G. Knepley     }
67859b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
67869b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
67879b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
67889b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
6789b5da9499SMatthew G. Knepley     /* Edge vertices have the average of endpoint coordinates */
6790b5da9499SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
6791b5da9499SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (e - eStart);
6792b5da9499SMatthew G. Knepley       const PetscInt *cone;
6793b5da9499SMatthew G. Knepley       PetscInt        coneSize, offA, offB, offnew, d;
6794b5da9499SMatthew G. Knepley 
6795b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr);
6796b5da9499SMatthew G. Knepley       if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize);
6797b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
679890b157c4SStefano Zampini       if (localize) {
67993548e9b6SStefano Zampini         PetscInt   coff, toffA = -1, toffB = -1, voffA, voffB;
680090b157c4SStefano Zampini         PetscInt  *eStar = NULL, eStarSize;
680190b157c4SStefano Zampini         PetscInt  *rStar = NULL, rStarSize;
68029fc2a3f3SStefano Zampini         PetscBool  cellfound = PETSC_FALSE;
680390b157c4SStefano Zampini 
680490b157c4SStefano Zampini         offA = offB = -1;
680590b157c4SStefano Zampini         ierr = PetscSectionGetOffset(coordSection, cone[0], &voffA);CHKERRQ(ierr);
680690b157c4SStefano Zampini         ierr = PetscSectionGetOffset(coordSection, cone[1], &voffB);CHKERRQ(ierr);
680790b157c4SStefano Zampini         ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr);
680890b157c4SStefano Zampini         ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
680990b157c4SStefano Zampini         for (v = 0; v < eStarSize*2; v += 2) {
681090b157c4SStefano Zampini           if ((eStar[v] >= cStart) && (eStar[v] < cEnd)) {
681190b157c4SStefano Zampini             PetscScalar     coordsNewAux[3];
681290b157c4SStefano Zampini             PetscInt       *cellCone = NULL;
68139fc2a3f3SStefano Zampini             PetscInt        cellClosureSize, s, cv, cdof;
681490b157c4SStefano Zampini             PetscBool       locvA = PETSC_TRUE, locvB = PETSC_TRUE;
681590b157c4SStefano Zampini             const PetscInt  cell = eStar[v];
681690b157c4SStefano Zampini 
68179fc2a3f3SStefano Zampini             ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr);
68189fc2a3f3SStefano Zampini             if (!cdof) {
68199fc2a3f3SStefano Zampini               /* Found a valid edge for the "vertex" part of the Section */
68209fc2a3f3SStefano Zampini               offA = voffA;
68219fc2a3f3SStefano Zampini               offB = voffB;
68229fc2a3f3SStefano Zampini               cellfound = PETSC_TRUE;
68239fc2a3f3SStefano Zampini             } else {
682490b157c4SStefano Zampini               ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr);
682590b157c4SStefano Zampini               ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr);
682690b157c4SStefano Zampini               for (s = 0, cv = 0; s < cellClosureSize*2; s += 2) {
682790b157c4SStefano Zampini                 const PetscInt point = cellCone[s];
682890b157c4SStefano Zampini                 if ((point >= vStart) && (point < vEnd)) {
682990b157c4SStefano Zampini                   if (point == cone[0]) toffA = spaceDim*cv + coff;
683090b157c4SStefano Zampini                   else if (point == cone[1]) toffB = spaceDim*cv + coff;
683190b157c4SStefano Zampini                   cv++;
683290b157c4SStefano Zampini                 }
683390b157c4SStefano Zampini               }
683490b157c4SStefano Zampini               ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr);
683590b157c4SStefano Zampini               for (d = 0; d < spaceDim; ++d) {
683690b157c4SStefano Zampini                 coordsNewAux[d] = 0.5*(coords[toffA+d] + coords[toffB+d]);
683790b157c4SStefano Zampini                 if (coords[toffA+d] != coords[voffA+d]) locvA = PETSC_FALSE;
683890b157c4SStefano Zampini                 if (coords[toffB+d] != coords[voffB+d]) locvB = PETSC_FALSE;
683990b157c4SStefano Zampini               }
684090b157c4SStefano Zampini               /* Found a valid edge for the "vertex" part of the Section */
68419fc2a3f3SStefano Zampini               if (!cellfound && (locvA || locvB)) {
68429fc2a3f3SStefano Zampini                 cellfound = PETSC_TRUE;
68439fc2a3f3SStefano Zampini                 offA = toffA;
68449fc2a3f3SStefano Zampini                 offB = toffB;
68459fc2a3f3SStefano Zampini               }
68469fc2a3f3SStefano Zampini             }
684790b157c4SStefano Zampini 
684890b157c4SStefano Zampini             /* Localize new coordinates on each refined cell */
684990b157c4SStefano Zampini             for (s = 0; s < rStarSize*2; s += 2) {
685090b157c4SStefano Zampini               if ((rStar[s] >= cStartNew) && (rStar[s] < cEndNew) && parentId[rStar[s]-cStartNew] == cell) {
68519fc2a3f3SStefano Zampini                 PetscInt       *rcone = NULL, rclosureSize, lid, p, rcdof;
685290b157c4SStefano Zampini                 const PetscInt  rcell = rStar[s];
685390b157c4SStefano Zampini 
68549fc2a3f3SStefano Zampini                 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr);
68559fc2a3f3SStefano Zampini                 if (!rcdof) continue;
685690b157c4SStefano Zampini                 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &coff);CHKERRQ(ierr);
685790b157c4SStefano Zampini                 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr);
685890b157c4SStefano Zampini                 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) {
685990b157c4SStefano Zampini                   if (rcone[p] == newv) {
686090b157c4SStefano Zampini                     for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNewAux[d];
686190b157c4SStefano Zampini                     break;
686290b157c4SStefano Zampini                   }
686390b157c4SStefano Zampini                   if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++;
686490b157c4SStefano Zampini                 }
686590b157c4SStefano Zampini                 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr);
686690b157c4SStefano Zampini                 if (p == rclosureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv);
686790b157c4SStefano Zampini               }
686890b157c4SStefano Zampini             }
686990b157c4SStefano Zampini           }
687090b157c4SStefano Zampini         }
687190b157c4SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr);
687290b157c4SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
68739fc2a3f3SStefano Zampini         if (!cellfound) {
68741072f78bSStefano Zampini           /* Could not find a valid edge for the vertex part, we will get this vertex later (final reduction) */
68751072f78bSStefano Zampini           needcoords = PETSC_TRUE;
687690b157c4SStefano Zampini         }
687790b157c4SStefano Zampini       } else {
6878b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr);
6879b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr);
688090b157c4SStefano Zampini       }
6881b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
688290b157c4SStefano Zampini       if (offA != -1 && offB != -1) {
68832e17dfb7SMatthew G. Knepley         ierr = DMLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr);
6884f1d7821bSLawrence Mitchell         for (d = 0; d < spaceDim; ++d) {
6885a96104c9SMatthew G. Knepley           coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]);
6886b5da9499SMatthew G. Knepley         }
688790b157c4SStefano Zampini       } else {
68881072f78bSStefano Zampini         for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL;
688990b157c4SStefano Zampini       }
6890b5da9499SMatthew G. Knepley     }
689175d3a19aSMatthew G. Knepley     /* Old vertices have the same coordinates */
689275d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
689375d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (v - vStart);
689475d3a19aSMatthew G. Knepley       PetscInt       off, offnew, d;
689575d3a19aSMatthew G. Knepley 
689675d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr);
689775d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
6898f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) {
689975d3a19aSMatthew G. Knepley         coordsNew[offnew+d] = coords[off+d];
690075d3a19aSMatthew G. Knepley       }
690190b157c4SStefano Zampini 
690290b157c4SStefano Zampini       /* Localize new coordinates on each refined cell */
690390b157c4SStefano Zampini       if (localize) {
690490b157c4SStefano Zampini         PetscInt  p;
690590b157c4SStefano Zampini         PetscInt *rStar = NULL, rStarSize;
690690b157c4SStefano Zampini 
690790b157c4SStefano Zampini         ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
690890b157c4SStefano Zampini         for (p = 0; p < rStarSize*2; p += 2) {
690990b157c4SStefano Zampini           if ((rStar[p] >= cStartNew) && (rStar[p] < cEndNew)) {
691090b157c4SStefano Zampini             PetscScalar  ocoords[3];
69119fc2a3f3SStefano Zampini             PetscInt    *cone = NULL, closureSize, lid, coff, s, oc, cdof;
691290b157c4SStefano Zampini 
691390b157c4SStefano Zampini             c    = rStar[p];
691490b157c4SStefano Zampini             oc   = parentId[c-cStartNew];
69159fc2a3f3SStefano Zampini             ierr = PetscSectionGetDof(coordSectionNew, c, &cdof);CHKERRQ(ierr);
69169fc2a3f3SStefano Zampini             if (!cdof) continue;
69179fc2a3f3SStefano Zampini             ierr = PetscSectionGetDof(coordSection, oc, &cdof);CHKERRQ(ierr);
69189fc2a3f3SStefano Zampini             if (!cdof) continue;
691990b157c4SStefano Zampini             ierr = PetscSectionGetOffset(coordSection, oc, &coff);CHKERRQ(ierr);
692090b157c4SStefano Zampini             ierr = DMPlexGetTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
692190b157c4SStefano Zampini             for (s = 0, lid = 0; s < closureSize*2; s += 2) {
692290b157c4SStefano Zampini               if (cone[s] == v) {
692390b157c4SStefano Zampini                 for (d = 0; d < spaceDim; d++) ocoords[d] = coords[coff + lid*spaceDim + d];
692490b157c4SStefano Zampini                 break;
692590b157c4SStefano Zampini               }
692690b157c4SStefano Zampini               if (cone[s] >= vStart && cone[s] < vEnd) lid++;
692790b157c4SStefano Zampini             }
692890b157c4SStefano Zampini             if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map old vertex %D\n",v);
692990b157c4SStefano Zampini             ierr = DMPlexRestoreTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
693090b157c4SStefano Zampini 
693190b157c4SStefano Zampini             ierr = PetscSectionGetOffset(coordSectionNew, c, &coff);CHKERRQ(ierr);
693290b157c4SStefano Zampini             ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
693390b157c4SStefano Zampini             for (s = 0, lid = 0; s < closureSize*2; s += 2) {
693490b157c4SStefano Zampini               if (cone[s] == newv) {
693590b157c4SStefano Zampini                 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = ocoords[d];
693690b157c4SStefano Zampini                 break;
693790b157c4SStefano Zampini               }
693890b157c4SStefano Zampini               if (cone[s] >= vStartNew && cone[s] < vEndNew) lid++;
693990b157c4SStefano Zampini             }
694090b157c4SStefano Zampini             if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv);
694190b157c4SStefano Zampini             ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
694290b157c4SStefano Zampini           }
694390b157c4SStefano Zampini         }
694490b157c4SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
694590b157c4SStefano Zampini       }
694675d3a19aSMatthew G. Knepley     }
6947b5da9499SMatthew G. Knepley     break;
6948b5da9499SMatthew G. Knepley   default:
6949b5da9499SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
695075d3a19aSMatthew G. Knepley   }
695175d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr);
695275d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
695375d3a19aSMatthew G. Knepley   ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr);
695490b157c4SStefano Zampini 
695590b157c4SStefano Zampini   /* Final reduction (if needed) if we are localizing */
695690b157c4SStefano Zampini   if (localize) {
69571072f78bSStefano Zampini     PetscBool gred;
695890b157c4SStefano Zampini 
69591072f78bSStefano Zampini     ierr = MPIU_Allreduce(&needcoords, &gred, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)rdm));CHKERRQ(ierr);
696090b157c4SStefano Zampini     if (gred) {
696190b157c4SStefano Zampini       DM                 cdm;
69621072f78bSStefano Zampini       Vec                aux;
69631072f78bSStefano Zampini       PetscSF            sf;
69641072f78bSStefano Zampini       const PetscScalar *lArray;
69659fc2a3f3SStefano Zampini       PetscScalar       *gArray;
696690b157c4SStefano Zampini 
696790b157c4SStefano Zampini       ierr = DMGetCoordinateDM(rdm, &cdm);CHKERRQ(ierr);
696890b157c4SStefano Zampini       ierr = DMCreateGlobalVector(cdm, &aux);CHKERRQ(ierr);
69691072f78bSStefano Zampini       ierr = DMGetDefaultSF(cdm, &sf);CHKERRQ(ierr);
69701072f78bSStefano Zampini       ierr = VecGetArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr);
69711072f78bSStefano Zampini       ierr = VecSet(aux, PETSC_MIN_REAL);CHKERRQ(ierr);
69721072f78bSStefano Zampini       ierr = VecGetArray(aux, &gArray);CHKERRQ(ierr);
69731072f78bSStefano Zampini       ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr);
69741072f78bSStefano Zampini       ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr);
69751072f78bSStefano Zampini       ierr = VecRestoreArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr);
69761072f78bSStefano Zampini       ierr = VecRestoreArray(aux, &gArray);CHKERRQ(ierr);
697790b157c4SStefano Zampini       ierr = DMGlobalToLocalBegin(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr);
697890b157c4SStefano Zampini       ierr = DMGlobalToLocalEnd(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr);
697990b157c4SStefano Zampini       ierr = VecDestroy(&aux);CHKERRQ(ierr);
698090b157c4SStefano Zampini     }
698190b157c4SStefano Zampini   }
698275d3a19aSMatthew G. Knepley   ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr);
698375d3a19aSMatthew G. Knepley   ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr);
698490b157c4SStefano Zampini   ierr = PetscFree(parentId);CHKERRQ(ierr);
698575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
698675d3a19aSMatthew G. Knepley }
698775d3a19aSMatthew G. Knepley 
6988963fc26aSMatthew G. Knepley /*@
6989963fc26aSMatthew G. Knepley   DMPlexCreateProcessSF - Create an SF which just has process connectivity
6990963fc26aSMatthew G. Knepley 
6991963fc26aSMatthew G. Knepley   Collective on DM
6992963fc26aSMatthew G. Knepley 
6993963fc26aSMatthew G. Knepley   Input Parameters:
6994963fc26aSMatthew G. Knepley + dm      - The DM
6995963fc26aSMatthew G. Knepley - sfPoint - The PetscSF which encodes point connectivity
6996963fc26aSMatthew G. Knepley 
6997963fc26aSMatthew G. Knepley   Output Parameters:
6998963fc26aSMatthew G. Knepley + processRanks - A list of process neighbors, or NULL
6999963fc26aSMatthew G. Knepley - sfProcess    - An SF encoding the process connectivity, or NULL
7000963fc26aSMatthew G. Knepley 
7001963fc26aSMatthew G. Knepley   Level: developer
7002963fc26aSMatthew G. Knepley 
7003963fc26aSMatthew G. Knepley .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF()
7004963fc26aSMatthew G. Knepley @*/
7005963fc26aSMatthew G. Knepley PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
700675d3a19aSMatthew G. Knepley {
700775d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, l;
700875d3a19aSMatthew G. Knepley   const PetscInt    *localPoints;
700975d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
701075d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
701175d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
701275d3a19aSMatthew G. Knepley   PetscInt          *ranks, *ranksNew;
70139852e123SBarry Smith   PetscMPIInt        size;
701475d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
701575d3a19aSMatthew G. Knepley 
701675d3a19aSMatthew G. Knepley   PetscFunctionBegin;
7017963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7018963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2);
7019963fc26aSMatthew G. Knepley   if (processRanks) {PetscValidPointer(processRanks, 3);}
7020963fc26aSMatthew G. Knepley   if (sfProcess)    {PetscValidPointer(sfProcess, 4);}
70219852e123SBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr);
702275d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
7023785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr);
702475d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
702575d3a19aSMatthew G. Knepley     ranks[l] = remotePoints[l].rank;
702675d3a19aSMatthew G. Knepley   }
702775d3a19aSMatthew G. Knepley   ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr);
7028785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr);
7029785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr);
7030785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr);
703175d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
703275d3a19aSMatthew G. Knepley     ranksNew[l]              = ranks[l];
703375d3a19aSMatthew G. Knepley     localPointsNew[l]        = l;
703475d3a19aSMatthew G. Knepley     remotePointsNew[l].index = 0;
703575d3a19aSMatthew G. Knepley     remotePointsNew[l].rank  = ranksNew[l];
703675d3a19aSMatthew G. Knepley   }
703775d3a19aSMatthew G. Knepley   ierr = PetscFree(ranks);CHKERRQ(ierr);
7038963fc26aSMatthew G. Knepley   if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);}
7039963fc26aSMatthew G. Knepley   else              {ierr = PetscFree(ranksNew);CHKERRQ(ierr);}
7040963fc26aSMatthew G. Knepley   if (sfProcess) {
704175d3a19aSMatthew G. Knepley     ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr);
7042963fc26aSMatthew G. Knepley     ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr);
704375d3a19aSMatthew G. Knepley     ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr);
70449852e123SBarry Smith     ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
7045963fc26aSMatthew G. Knepley   }
704675d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
704775d3a19aSMatthew G. Knepley }
704875d3a19aSMatthew G. Knepley 
704986150812SJed Brown static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
705075d3a19aSMatthew G. Knepley {
705175d3a19aSMatthew G. Knepley   PetscSF            sf, sfNew, sfProcess;
705275d3a19aSMatthew G. Knepley   IS                 processRanks;
705375d3a19aSMatthew G. Knepley   MPI_Datatype       depthType;
705475d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, numLeavesNew = 0, l, m;
705575d3a19aSMatthew G. Knepley   const PetscInt    *localPoints, *neighbors;
705675d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
705775d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
705875d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
705975d3a19aSMatthew G. Knepley   PetscInt          *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew;
706037d81139SMatthew G. Knepley   PetscInt           ldepth, depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n;
70617ba685a0SMatthew G. Knepley   PetscInt           cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
706275d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
706375d3a19aSMatthew G. Knepley 
706475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
706575d3a19aSMatthew G. Knepley   ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr);
706637d81139SMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &ldepth);CHKERRQ(ierr);
706737d81139SMatthew G. Knepley   ierr = MPIU_Allreduce(&ldepth, &depth, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr);
706837d81139SMatthew G. Knepley   if ((ldepth >= 0) && (depth != ldepth)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent Plex depth %d != %d", ldepth, depth);
706975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
707075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
707175d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
707275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
707375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
7074add09238SMatthew G. Knepley   cMax = cMax < 0 ? cEnd : cMax;
7075add09238SMatthew G. Knepley   fMax = fMax < 0 ? fEnd : fMax;
7076add09238SMatthew G. Knepley   eMax = eMax < 0 ? eEnd : eMax;
70773478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
707875d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
707975d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr);
7080add09238SMatthew G. Knepley   /* Calculate size of new SF */
708175d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
708275d3a19aSMatthew G. Knepley   if (numRoots < 0) PetscFunctionReturn(0);
708375d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
708475d3a19aSMatthew G. Knepley     const PetscInt p = localPoints[l];
708575d3a19aSMatthew G. Knepley 
708675d3a19aSMatthew G. Knepley     switch (refiner) {
70870314a74cSLawrence Mitchell     case REFINER_SIMPLEX_1D:
70880314a74cSLawrence Mitchell       if ((p >= vStart) && (p < vEnd)) {
70890314a74cSLawrence Mitchell         /* Interior vertices stay the same */
70900314a74cSLawrence Mitchell         ++numLeavesNew;
70910314a74cSLawrence Mitchell       } else if ((p >= cStart && p < cMax)) {
70920314a74cSLawrence Mitchell         /* Interior cells add new cells and interior vertices */
70930314a74cSLawrence Mitchell         numLeavesNew += 2 + 1;
70940314a74cSLawrence Mitchell       }
70950314a74cSLawrence Mitchell       break;
70969b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_2D:
70979b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_2D:
7098a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
7099a97b51b8SMatthew G. Knepley         /* Interior vertices stay the same */
7100a97b51b8SMatthew G. Knepley         ++numLeavesNew;
7101a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
7102a97b51b8SMatthew G. Knepley         /* Interior faces add new faces and vertex */
7103a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
7104a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
7105a97b51b8SMatthew G. Knepley         /* Hybrid faces stay the same */
7106a97b51b8SMatthew G. Knepley         ++numLeavesNew;
7107a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
7108a97b51b8SMatthew G. Knepley         /* Interior cells add new cells and interior faces */
7109a97b51b8SMatthew G. Knepley         numLeavesNew += 4 + 3;
7110a97b51b8SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
7111a97b51b8SMatthew G. Knepley         /* Hybrid cells add new cells and hybrid face */
7112a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
7113a97b51b8SMatthew G. Knepley       }
7114a97b51b8SMatthew G. Knepley       break;
7115e5337592SStefano Zampini     case REFINER_SIMPLEX_TO_HEX_2D:
7116e5337592SStefano Zampini       if ((p >= vStart) && (p < vEnd)) {
7117e5337592SStefano Zampini         /* Interior vertices stay the same */
7118e5337592SStefano Zampini         ++numLeavesNew;
7119e5337592SStefano Zampini       } else if ((p >= fStart) && (p < fEnd)) {
7120e5337592SStefano Zampini         /* Interior faces add new faces and vertex */
7121e5337592SStefano Zampini         numLeavesNew += 2 + 1;
7122e5337592SStefano Zampini       } else if ((p >= cStart) && (p < cEnd)) {
7123e5337592SStefano Zampini         /* Interior cells add new cells, interior faces, and vertex */
7124e5337592SStefano Zampini         numLeavesNew += 3 + 3 + 1;
7125e5337592SStefano Zampini       }
7126e5337592SStefano Zampini       break;
71279b1a0e7fSLawrence Mitchell     case REFINER_HEX_2D:
71289b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_2D:
7129a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
7130a97b51b8SMatthew G. Knepley         /* Interior vertices stay the same */
7131a97b51b8SMatthew G. Knepley         ++numLeavesNew;
7132a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
7133a97b51b8SMatthew G. Knepley         /* Interior faces add new faces and vertex */
7134a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
7135a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
7136a97b51b8SMatthew G. Knepley         /* Hybrid faces stay the same */
7137a97b51b8SMatthew G. Knepley         ++numLeavesNew;
7138a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
7139a97b51b8SMatthew G. Knepley         /* Interior cells add new cells, interior faces, and vertex */
7140a97b51b8SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
7141a97b51b8SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
7142a97b51b8SMatthew G. Knepley         /* Hybrid cells add new cells and hybrid face */
7143a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
7144a97b51b8SMatthew G. Knepley       }
7145a97b51b8SMatthew G. Knepley       break;
71469b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_3D:
71479b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_3D:
71486ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
71496ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
71506ce3c06aSMatthew G. Knepley         ++numLeavesNew;
71516ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
71526ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
71536ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
71546ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
71556ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
71566ce3c06aSMatthew G. Knepley         ++numLeavesNew;
71576ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
71586ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
71596ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
71606ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
71616ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
71626ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
71636ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
71646ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
71656ce3c06aSMatthew G. Knepley         numLeavesNew += 8 + 8 + 1;
71666ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
71676ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
71686ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
71696ce3c06aSMatthew G. Knepley       }
71706ce3c06aSMatthew G. Knepley       break;
7171e5337592SStefano Zampini     case REFINER_SIMPLEX_TO_HEX_3D:
7172e5337592SStefano Zampini       if ((p >= vStart) && (p < vEnd)) {
7173e5337592SStefano Zampini         /* Interior vertices stay the same */
7174e5337592SStefano Zampini         ++numLeavesNew;
7175e5337592SStefano Zampini       } else if ((p >= eStart) && (p < eEnd)) {
7176e5337592SStefano Zampini         /* Interior edges add new edges and vertex */
7177e5337592SStefano Zampini         numLeavesNew += 2 + 1;
7178e5337592SStefano Zampini       } else if ((p >= fStart) && (p < fEnd)) {
7179e5337592SStefano Zampini         /* Interior faces add new faces, edges and a vertex */
7180e5337592SStefano Zampini         numLeavesNew += 3 + 3 + 1;
7181e5337592SStefano Zampini       } else if ((p >= cStart) && (p < cEnd)) {
7182e5337592SStefano Zampini         /* Interior cells add new cells, faces, edges and a vertex */
7183e5337592SStefano Zampini         numLeavesNew += 4 + 6 + 4 + 1;
7184e5337592SStefano Zampini       }
7185e5337592SStefano Zampini       break;
71869b1a0e7fSLawrence Mitchell     case REFINER_HEX_3D:
71879b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_3D:
718827fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
718927fcede3SMatthew G. Knepley         /* Old vertices stay the same */
719027fcede3SMatthew G. Knepley         ++numLeavesNew;
719127fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
719227fcede3SMatthew G. Knepley         /* Interior edges add new edges, and vertex */
719327fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
719427fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
719527fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
719627fcede3SMatthew G. Knepley         ++numLeavesNew;
719727fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
719827fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
719927fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
720027fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
720127fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
720227fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
720327fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
720427fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
720527fcede3SMatthew G. Knepley         numLeavesNew += 8 + 12 + 6 + 1;
720627fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
720727fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
720827fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
720927fcede3SMatthew G. Knepley       }
721027fcede3SMatthew G. Knepley       break;
721175d3a19aSMatthew G. Knepley     default:
721275d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
721375d3a19aSMatthew G. Knepley     }
721475d3a19aSMatthew G. Knepley   }
721575d3a19aSMatthew G. Knepley   /* Communicate depthSizes for each remote rank */
721675d3a19aSMatthew G. Knepley   ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr);
721775d3a19aSMatthew G. Knepley   ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr);
7218dcca6d9dSJed Brown   ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr);
7219dcca6d9dSJed Brown   ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr);
722075d3a19aSMatthew G. Knepley   ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr);
722175d3a19aSMatthew G. Knepley   ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr);
722275d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
722375d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
722475d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
722575d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr);
722675d3a19aSMatthew G. Knepley   }
722775d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cMax;
722875d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vMax;
722975d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fMax;
723075d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eMax;
723175d3a19aSMatthew G. Knepley 
723275d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
723375d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
723475d3a19aSMatthew G. Knepley 
723575d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cEnd - cStart;
723675d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vEnd - vStart;
723775d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fEnd - fStart;
723875d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eEnd - eStart;
723975d3a19aSMatthew G. Knepley 
724075d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
724175d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
724275d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
724375d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr);
72440252e7f5SMatthew 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];
72450252e7f5SMatthew 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];
72460252e7f5SMatthew 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];
724775d3a19aSMatthew G. Knepley   }
724875d3a19aSMatthew G. Knepley   ierr = MPI_Type_free(&depthType);CHKERRQ(ierr);
724975d3a19aSMatthew G. Knepley   ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr);
725075d3a19aSMatthew G. Knepley   /* Calculate new point SF */
7251785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr);
7252785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr);
725375d3a19aSMatthew G. Knepley   ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr);
725475d3a19aSMatthew G. Knepley   for (l = 0, m = 0; l < numLeaves; ++l) {
725575d3a19aSMatthew G. Knepley     PetscInt    p     = localPoints[l];
725675d3a19aSMatthew G. Knepley     PetscInt    rp    = remotePoints[l].index, n;
725775d3a19aSMatthew G. Knepley     PetscMPIInt rrank = remotePoints[l].rank;
725875d3a19aSMatthew G. Knepley 
725975d3a19aSMatthew G. Knepley     ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr);
726075d3a19aSMatthew G. Knepley     if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank);
726175d3a19aSMatthew G. Knepley     switch (refiner) {
72620314a74cSLawrence Mitchell     case REFINER_SIMPLEX_1D:
72630314a74cSLawrence Mitchell       if ((p >= vStart) && (p < vEnd)) {
72640314a74cSLawrence Mitchell         /* Old vertices stay the same */
72650314a74cSLawrence Mitchell         localPointsNew[m]        = vStartNew     + (p  - vStart);
72660314a74cSLawrence Mitchell         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
72670314a74cSLawrence Mitchell         remotePointsNew[m].rank  = rrank;
72680314a74cSLawrence Mitchell         ++m;
72690314a74cSLawrence Mitchell       } else if ((p >= cStart) && (p < cMax)) {
72700314a74cSLawrence Mitchell         /* Old interior cells add new cells and vertex */
72710314a74cSLawrence Mitchell         for (r = 0; r < 2; ++r, ++m) {
72720314a74cSLawrence Mitchell           localPointsNew[m]        = cStartNew     + (p  - cStart)*2     + r;
72730314a74cSLawrence Mitchell           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r;
72740314a74cSLawrence Mitchell           remotePointsNew[m].rank  = rrank;
72750314a74cSLawrence Mitchell         }
72760314a74cSLawrence Mitchell         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - cStart);
72770314a74cSLawrence Mitchell         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]);
72780314a74cSLawrence Mitchell         remotePointsNew[m].rank  = rrank;
72790314a74cSLawrence Mitchell         ++m;
72800314a74cSLawrence Mitchell       }
72810314a74cSLawrence Mitchell       break;
72829b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_2D:
72839b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_2D:
728475d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
728575d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
728675d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
728775d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
728875d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
728975d3a19aSMatthew G. Knepley         ++m;
729075d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
729175d3a19aSMatthew G. Knepley         /* Old interior faces add new faces and vertex */
729275d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
729375d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
729475d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
729575d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
729675d3a19aSMatthew G. Knepley         }
7297add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
7298add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
7299add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
7300add09238SMatthew G. Knepley         ++m;
730175d3a19aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
730275d3a19aSMatthew G. Knepley         /* Old hybrid faces stay the same */
730375d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
730475d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
730575d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
730675d3a19aSMatthew G. Knepley         ++m;
730775d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
730875d3a19aSMatthew G. Knepley         /* Old interior cells add new cells and interior faces */
730975d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
731075d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
731175d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
731275d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
731375d3a19aSMatthew G. Knepley         }
731475d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
731575d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*3     + r;
731675d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r;
731775d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
731875d3a19aSMatthew G. Knepley         }
7319add09238SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
732075d3a19aSMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
732175d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
732275d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
732375d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
732475d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
732575d3a19aSMatthew G. Knepley         }
732675d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*3     + (p  - cMax);
732775d3a19aSMatthew 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]);
732875d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
732975d3a19aSMatthew G. Knepley         ++m;
733075d3a19aSMatthew G. Knepley       }
733175d3a19aSMatthew G. Knepley       break;
7332e5337592SStefano Zampini     case REFINER_SIMPLEX_TO_HEX_2D:
7333e5337592SStefano Zampini       if ((p >= vStart) && (p < vEnd)) {
7334e5337592SStefano Zampini         /* Old vertices stay the same */
7335e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (p  - vStart);
7336e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
7337e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7338e5337592SStefano Zampini         ++m;
7339e5337592SStefano Zampini       } else if ((p >= fStart) && (p < fEnd)) {
7340e5337592SStefano Zampini         /* Old interior faces add new faces and vertex */
7341e5337592SStefano Zampini         for (r = 0; r < 2; ++r, ++m) {
7342e5337592SStefano Zampini           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
7343e5337592SStefano Zampini           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
7344e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7345e5337592SStefano Zampini         }
7346e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
7347e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
7348e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7349e5337592SStefano Zampini         ++m;
7350e5337592SStefano Zampini       } else if ((p >= cStart) && (p < cEnd)) {
7351e5337592SStefano Zampini         /* Old interior cells add new cells, interior faces, and a vertex */
7352e5337592SStefano Zampini         for (r = 0; r < 3; ++r, ++m) {
7353e5337592SStefano Zampini           localPointsNew[m]        = cStartNew     + (p  - cStart)*3     + r;
7354e5337592SStefano Zampini           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*3 + r;
7355e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7356e5337592SStefano Zampini         }
7357e5337592SStefano Zampini         for (r = 0; r < 3; ++r, ++m) {
7358e5337592SStefano Zampini           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*2                    + (p  - cStart)*3     + r;
7359e5337592SStefano Zampini           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r;
7360e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7361e5337592SStefano Zampini         }
7362e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (fEnd - fStart)                    + (p  - cStart);
7363e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]);
7364e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7365e5337592SStefano Zampini         ++m;
7366e5337592SStefano Zampini       }
7367e5337592SStefano Zampini       break;
73689b1a0e7fSLawrence Mitchell     case REFINER_HEX_2D:
73699b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_2D:
7370a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
7371a97b51b8SMatthew G. Knepley         /* Old vertices stay the same */
7372a97b51b8SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
7373a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
7374a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
7375a97b51b8SMatthew G. Knepley         ++m;
7376a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
7377a97b51b8SMatthew G. Knepley         /* Old interior faces add new faces and vertex */
7378a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
7379a97b51b8SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
7380a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
7381a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
7382a97b51b8SMatthew G. Knepley         }
7383add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
7384add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
7385add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
7386add09238SMatthew G. Knepley         ++m;
7387a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
7388a97b51b8SMatthew G. Knepley         /* Old hybrid faces stay the same */
7389a97b51b8SMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
7390a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
7391a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
7392a97b51b8SMatthew G. Knepley         ++m;
7393a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
7394a97b51b8SMatthew G. Knepley         /* Old interior cells add new cells, interior faces, and vertex */
7395a97b51b8SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
7396a97b51b8SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
7397a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
7398a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
7399a97b51b8SMatthew G. Knepley         }
7400a97b51b8SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
7401a97b51b8SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*4     + r;
7402a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r;
7403a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
7404a97b51b8SMatthew G. Knepley         }
7405add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)               + (fMax                              - fStart)     + (p  - cStart);
7406add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0]  + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]);
7407add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
7408add09238SMatthew G. Knepley         ++m;
7409a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
7410a97b51b8SMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
7411a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
7412a97b51b8SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
7413a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
7414a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
7415a97b51b8SMatthew G. Knepley         }
7416a97b51b8SMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*4     + (p  - cMax);
7417a97b51b8SMatthew 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]);
7418a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
7419a97b51b8SMatthew G. Knepley         ++m;
7420a97b51b8SMatthew G. Knepley       }
7421a97b51b8SMatthew G. Knepley       break;
74229b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_3D:
74239b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_3D:
74246ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
74256ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
74266ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
74276ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
74286ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
74296ce3c06aSMatthew G. Knepley         ++m;
74306ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
74316ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
74326ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
74336ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
74346ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
74356ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
74366ce3c06aSMatthew G. Knepley         }
74376ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
74386ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
74396ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
74406ce3c06aSMatthew G. Knepley         ++m;
74416ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
74426ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
74436ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (p  - eMax);
74447d5cd7d5SMatthew 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]);
74456ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
74466ce3c06aSMatthew G. Knepley         ++m;
74476ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
74486ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
74496ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
74506ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
74516ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
74526ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
74536ce3c06aSMatthew G. Knepley         }
74546ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
74556ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*3     + r;
74566ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r;
74576ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
74586ce3c06aSMatthew G. Knepley         }
74596ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
74606ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
74616ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
7462899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (p  - fMax)*2                              + r;
7463899f98d0SMatthew 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;
74646ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
74656ce3c06aSMatthew G. Knepley         }
74667d5cd7d5SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (eEnd                                    - eMax)                        + (p  - fMax);
74677d5cd7d5SMatthew 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]);
74686ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
746909b1338fSMatthew G. Knepley         ++m;
74706ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
74716ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
74726ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
74736ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
74746ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
74756ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
74766ce3c06aSMatthew G. Knepley         }
74776ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
74786ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*8     + r;
74796ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r;
74806ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
74816ce3c06aSMatthew G. Knepley         }
7482c7c54c77SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (p  - cStart)*1     + 0;
7483c7c54c77SMatthew 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;
74846ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
748509b1338fSMatthew G. Knepley         ++m;
74866ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
74876ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
74886ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
74896ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
74906ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
74916ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
74926ce3c06aSMatthew G. Knepley         }
74936ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
7494899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (fEnd                                          - fMax)*2                              + (p  - cMax)*3                            + r;
7495899f98d0SMatthew 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;
74966ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
74976ce3c06aSMatthew G. Knepley         }
74986ce3c06aSMatthew G. Knepley       }
74996ce3c06aSMatthew G. Knepley       break;
7500e5337592SStefano Zampini     case REFINER_SIMPLEX_TO_HEX_3D:
7501e5337592SStefano Zampini       if ((p >= vStart) && (p < vEnd)) {
7502e5337592SStefano Zampini         /* Interior vertices stay the same */
7503e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (p  - vStart);
7504e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
7505e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7506e5337592SStefano Zampini         ++m;
7507e5337592SStefano Zampini       } else if ((p >= eStart) && (p < eEnd)) {
7508e5337592SStefano Zampini         /* Interior edges add new edges and vertex */
7509e5337592SStefano Zampini         for (r = 0; r < 2; ++r, ++m) {
7510e5337592SStefano Zampini           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
7511e5337592SStefano Zampini           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
7512e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7513e5337592SStefano Zampini         }
7514e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
7515e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
7516e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7517e5337592SStefano Zampini         ++m;
7518e5337592SStefano Zampini       } else if ((p >= fStart) && (p < fEnd)) {
7519e5337592SStefano Zampini         /* Interior faces add new faces, edges and a vertex */
7520e5337592SStefano Zampini         for (r = 0; r < 3; ++r, ++m) {
7521e5337592SStefano Zampini           localPointsNew[m]        = fStartNew     + (p  - fStart)*3     + r;
7522e5337592SStefano Zampini           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*3 + r;
7523e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7524e5337592SStefano Zampini         }
7525e5337592SStefano Zampini         for (r = 0; r < 3; ++r, ++m) {
7526e5337592SStefano Zampini           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2                + (p  - fStart)*3     + r;
7527e5337592SStefano Zampini           remotePointsNew[m].index = reStartNew[n] + (rdepthSizeOld[n*(depth+1)+1])*2 + (rp - rfStart[n])*3 + r;
7528e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7529e5337592SStefano Zampini         }
7530e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eEnd - eStart)              + (p - fStart);
7531e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]);
7532e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7533e5337592SStefano Zampini         ++m;
7534e5337592SStefano Zampini       } else if ((p >= cStart) && (p < cEnd)) {
7535e5337592SStefano Zampini         /* Interior cells add new cells, faces, edges, and a vertex */
7536e5337592SStefano Zampini         for (r = 0; r < 4; ++r, ++m) {
7537e5337592SStefano Zampini           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
7538e5337592SStefano Zampini           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
7539e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7540e5337592SStefano Zampini         }
7541e5337592SStefano Zampini         for (r = 0; r < 6; ++r, ++m) {
7542e5337592SStefano Zampini           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*3                    + (p  - cStart)*6     + r;
7543e5337592SStefano Zampini           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*6 + r;
7544e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7545e5337592SStefano Zampini         }
7546e5337592SStefano Zampini         for (r = 0; r < 4; ++r, ++m) {
7547e5337592SStefano Zampini           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (fEnd - fStart)*3                    + (p  - cStart)*4 + r;
7548e5337592SStefano Zampini           remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*4 + r;
7549e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7550e5337592SStefano Zampini         }
7551e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eEnd - eStart)              + (fEnd - fStart)                    + (p - cStart);
7552e5337592SStefano 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]);
7553e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7554e5337592SStefano Zampini         ++m;
7555e5337592SStefano Zampini       }
7556e5337592SStefano Zampini       break;
75579b1a0e7fSLawrence Mitchell     case REFINER_HEX_3D:
75589b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_3D:
755927fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
756027fcede3SMatthew G. Knepley         /* Interior vertices stay the same */
756127fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
756227fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
756327fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
756427fcede3SMatthew G. Knepley         ++m;
756527fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
756627fcede3SMatthew G. Knepley         /* Interior edges add new edges and vertex */
756727fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
756827fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
756927fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
757027fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
757127fcede3SMatthew G. Knepley         }
757227fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
757327fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
757427fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
757527fcede3SMatthew G. Knepley         ++m;
757627fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
757727fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
757827fcede3SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (p  - eMax);
7579d2701f60SMatthew 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]);
758027fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
758127fcede3SMatthew G. Knepley         ++m;
758227fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
758327fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
758427fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
758527fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
758627fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
758727fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
758827fcede3SMatthew G. Knepley         }
758927fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
759027fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*4     + r;
759127fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r;
759227fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
759327fcede3SMatthew G. Knepley         }
759427fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eMax                        - eStart)     + (p  - fStart);
759527fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]);
759627fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
759727fcede3SMatthew G. Knepley         ++m;
759827fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
759927fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
760027fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
7601d2701f60SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*12     + (p  - fMax)*2                              + r;
7602d2701f60SMatthew 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;
760327fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
760427fcede3SMatthew G. Knepley         }
7605d2701f60SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (eEnd                                    - eMax)                        + (p  - fMax);
7606d2701f60SMatthew 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]);
760727fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
760827fcede3SMatthew G. Knepley         ++m;
760927fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
761027fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
761127fcede3SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
761227fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
761327fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
761427fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
761527fcede3SMatthew G. Knepley         }
761627fcede3SMatthew G. Knepley         for (r = 0; r < 12; ++r, ++m) {
761727fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*12     + r;
761827fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r;
761927fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
762027fcede3SMatthew G. Knepley         }
762127fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r, ++m) {
762227fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (p  - cStart)*6     + r;
762327fcede3SMatthew 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;
762427fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
762527fcede3SMatthew G. Knepley         }
762627fcede3SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
762727fcede3SMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (eMax                        - eStart)     + (fMax                              - fStart)     + (p  - cStart)     + r;
762827fcede3SMatthew 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;
762927fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
763027fcede3SMatthew G. Knepley         }
763127fcede3SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
763227fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
763327fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
763427fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
763527fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
763627fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
763727fcede3SMatthew G. Knepley         }
763827fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
7639d2701f60SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*12     + (fEnd                                          - fMax)*2                              + (p  - cMax)*4                            + r;
7640d2701f60SMatthew 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;
764127fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
764227fcede3SMatthew G. Knepley         }
7643d2701f60SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (eEnd                                    - eMax)                        + (fEnd                                          - fMax)                              + (p  - cMax);
7644d2701f60SMatthew 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]);
764527fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
764627fcede3SMatthew G. Knepley         ++m;
764727fcede3SMatthew G. Knepley       }
764827fcede3SMatthew G. Knepley       break;
764975d3a19aSMatthew G. Knepley     default:
765075d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
765175d3a19aSMatthew G. Knepley     }
765275d3a19aSMatthew G. Knepley   }
765309b1338fSMatthew G. Knepley   if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew);
765475d3a19aSMatthew G. Knepley   ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr);
765575d3a19aSMatthew G. Knepley   ierr = ISDestroy(&processRanks);CHKERRQ(ierr);
7656ba3c3d50SMatthew G. Knepley   {
7657ba3c3d50SMatthew G. Knepley     PetscSFNode *rp, *rtmp;
7658ba3c3d50SMatthew G. Knepley     PetscInt    *lp, *idx, *ltmp, i;
7659ba3c3d50SMatthew G. Knepley 
7660ba3c3d50SMatthew G. Knepley     /* SF needs sorted leaves to correct calculate Gather */
7661ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr);
7662ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr);
7663ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr);
7664c7c54c77SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
7665c7c54c77SMatthew 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);
7666c7c54c77SMatthew G. Knepley       idx[i] = i;
7667c7c54c77SMatthew G. Knepley     }
7668ba3c3d50SMatthew G. Knepley     ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr);
7669ba3c3d50SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
7670ba3c3d50SMatthew G. Knepley       lp[i] = localPointsNew[idx[i]];
7671ba3c3d50SMatthew G. Knepley       rp[i] = remotePointsNew[idx[i]];
7672ba3c3d50SMatthew G. Knepley     }
7673ba3c3d50SMatthew G. Knepley     ltmp            = localPointsNew;
7674ba3c3d50SMatthew G. Knepley     localPointsNew  = lp;
7675ba3c3d50SMatthew G. Knepley     rtmp            = remotePointsNew;
7676ba3c3d50SMatthew G. Knepley     remotePointsNew = rp;
7677ba3c3d50SMatthew G. Knepley     ierr = PetscFree(idx);CHKERRQ(ierr);
7678ba3c3d50SMatthew G. Knepley     ierr = PetscFree(ltmp);CHKERRQ(ierr);
7679ba3c3d50SMatthew G. Knepley     ierr = PetscFree(rtmp);CHKERRQ(ierr);
7680ba3c3d50SMatthew G. Knepley   }
768175d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
768275d3a19aSMatthew G. Knepley   ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr);
768306a0ba2dSMatthew G. Knepley   ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr);
768475d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
768575d3a19aSMatthew G. Knepley }
768675d3a19aSMatthew G. Knepley 
768786150812SJed Brown static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
768875d3a19aSMatthew G. Knepley {
768975d3a19aSMatthew G. Knepley   PetscInt       numLabels, l;
76907ba685a0SMatthew G. Knepley   PetscInt       depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r;
76917ba685a0SMatthew G. Knepley   PetscInt       cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
769275d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
769375d3a19aSMatthew G. Knepley 
769475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
769575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
769675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
769775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
769875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
7699d963de37SMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
77003478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
7701c58f1c22SToby Isaac   ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr);
770275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
770375d3a19aSMatthew G. Knepley   switch (refiner) {
77049b1a0e7fSLawrence Mitchell   case REFINER_NOOP:
77050314a74cSLawrence Mitchell   case REFINER_SIMPLEX_1D:
77069b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
7707e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_2D:
77089b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
77099b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
77109b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
7711e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_3D:
77129b1a0e7fSLawrence Mitchell     break;
77139b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
77149b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
771558b8852aSMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
77169b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
77179b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
771875d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
771975d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
77201e317b1dSMatthew G. Knepley     break;
77219b1a0e7fSLawrence Mitchell   default:
77229b1a0e7fSLawrence Mitchell     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
772375d3a19aSMatthew G. Knepley   }
772475d3a19aSMatthew G. Knepley   for (l = 0; l < numLabels; ++l) {
772575d3a19aSMatthew G. Knepley     DMLabel         label, labelNew;
772675d3a19aSMatthew G. Knepley     const char     *lname;
772775d3a19aSMatthew G. Knepley     PetscBool       isDepth;
772875d3a19aSMatthew G. Knepley     IS              valueIS;
772975d3a19aSMatthew G. Knepley     const PetscInt *values;
77305aa44df4SToby Isaac     PetscInt        defVal;
773175d3a19aSMatthew G. Knepley     PetscInt        numValues, val;
773275d3a19aSMatthew G. Knepley 
7733c58f1c22SToby Isaac     ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr);
773475d3a19aSMatthew G. Knepley     ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr);
773575d3a19aSMatthew G. Knepley     if (isDepth) continue;
7736c58f1c22SToby Isaac     ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr);
7737c58f1c22SToby Isaac     ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr);
7738c58f1c22SToby Isaac     ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr);
77395aa44df4SToby Isaac     ierr = DMLabelGetDefaultValue(label,&defVal);CHKERRQ(ierr);
77405aa44df4SToby Isaac     ierr = DMLabelSetDefaultValue(labelNew,defVal);CHKERRQ(ierr);
774175d3a19aSMatthew G. Knepley     ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr);
774275d3a19aSMatthew G. Knepley     ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr);
774375d3a19aSMatthew G. Knepley     ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr);
774475d3a19aSMatthew G. Knepley     for (val = 0; val < numValues; ++val) {
774575d3a19aSMatthew G. Knepley       IS              pointIS;
774675d3a19aSMatthew G. Knepley       const PetscInt *points;
774775d3a19aSMatthew G. Knepley       PetscInt        numPoints, n;
774875d3a19aSMatthew G. Knepley 
774975d3a19aSMatthew G. Knepley       ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr);
775075d3a19aSMatthew G. Knepley       ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);
775175d3a19aSMatthew G. Knepley       ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr);
77522bc5314cSMichael Lange       /* Ensure refined label is created with same number of strata as
77532bc5314cSMichael Lange        * original (even if no entries here). */
7754ad8374ffSToby Isaac       ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr);
775575d3a19aSMatthew G. Knepley       for (n = 0; n < numPoints; ++n) {
775675d3a19aSMatthew G. Knepley         const PetscInt p = points[n];
775775d3a19aSMatthew G. Knepley         switch (refiner) {
77580314a74cSLawrence Mitchell         case REFINER_SIMPLEX_1D:
77590314a74cSLawrence Mitchell           if ((p >= vStart) && (p < vEnd)) {
77600314a74cSLawrence Mitchell             /* Old vertices stay the same */
77610314a74cSLawrence Mitchell             newp = vStartNew + (p - vStart);
77620314a74cSLawrence Mitchell             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
77630314a74cSLawrence Mitchell           } else if ((p >= cStart) && (p < cEnd)) {
77640314a74cSLawrence Mitchell             /* Old cells add new cells and vertex */
77650314a74cSLawrence Mitchell             newp = vStartNew + (vEnd - vStart) + (p - cStart);
77660314a74cSLawrence Mitchell             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
77670314a74cSLawrence Mitchell             for (r = 0; r < 2; ++r) {
77680314a74cSLawrence Mitchell               newp = cStartNew + (p - cStart)*2 + r;
77690314a74cSLawrence Mitchell               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
77700314a74cSLawrence Mitchell             }
77710314a74cSLawrence Mitchell           }
77720314a74cSLawrence Mitchell           break;
77739b1a0e7fSLawrence Mitchell         case REFINER_SIMPLEX_2D:
777475d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
777575d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
777675d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
777775d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
777875d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
777975d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
778075d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
778175d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
778275d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
778375d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
778475d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
778575d3a19aSMatthew G. Knepley             }
778675d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
778775d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces */
778875d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
778975d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
779075d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
779175d3a19aSMatthew G. Knepley             }
779275d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
779375d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
779475d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
779575d3a19aSMatthew G. Knepley             }
779675d3a19aSMatthew G. Knepley           }
779775d3a19aSMatthew G. Knepley           break;
7798e5337592SStefano Zampini         case REFINER_SIMPLEX_TO_HEX_2D:
7799e5337592SStefano Zampini           if ((p >= vStart) && (p < vEnd)) {
7800e5337592SStefano Zampini             /* Old vertices stay the same */
7801e5337592SStefano Zampini             newp = vStartNew + (p - vStart);
7802e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7803e5337592SStefano Zampini           } else if ((p >= fStart) && (p < fEnd)) {
7804e5337592SStefano Zampini             /* Old faces add new faces and vertex */
7805e5337592SStefano Zampini             newp = vStartNew + (vEnd - vStart) + (p - fStart);
7806e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7807e5337592SStefano Zampini             for (r = 0; r < 2; ++r) {
7808e5337592SStefano Zampini               newp = fStartNew + (p - fStart)*2 + r;
7809e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7810e5337592SStefano Zampini             }
7811e5337592SStefano Zampini           } else if ((p >= cStart) && (p < cEnd)) {
7812e5337592SStefano Zampini             /* Old cells add new cells, interior faces, and a vertex */
7813e5337592SStefano Zampini             for (r = 0; r < 3; ++r) {
7814e5337592SStefano Zampini               newp = cStartNew + (p - cStart)*3 + r;
7815e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7816e5337592SStefano Zampini             }
7817e5337592SStefano Zampini             for (r = 0; r < 3; ++r) {
7818e5337592SStefano Zampini               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
7819e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7820e5337592SStefano Zampini             }
7821e5337592SStefano Zampini             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p;
7822e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7823e5337592SStefano Zampini           }
7824e5337592SStefano Zampini           break;
78259b1a0e7fSLawrence Mitchell         case REFINER_HEX_2D:
782675d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
782775d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
782875d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
782975d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
783075d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
783175d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
783275d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
783375d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
783475d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
783575d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
783675d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
783775d3a19aSMatthew G. Knepley             }
783875d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
783975d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces and vertex */
784075d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
784175d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
784275d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
784375d3a19aSMatthew G. Knepley             }
784475d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
784575d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
784675d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
784775d3a19aSMatthew G. Knepley             }
784875d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
784975d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
785075d3a19aSMatthew G. Knepley           }
785175d3a19aSMatthew G. Knepley           break;
78529b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_SIMPLEX_2D:
785375d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
785475d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
785575d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
785675d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
785775d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
785875d3a19aSMatthew G. Knepley             /* Old interior faces add new faces and vertex */
785975d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
786075d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
786175d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
786275d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
786375d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
786475d3a19aSMatthew G. Knepley             }
786575d3a19aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
786675d3a19aSMatthew G. Knepley             /* Old hybrid faces stay the same */
786775d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
786875d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
786975d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
787075d3a19aSMatthew G. Knepley             /* Old interior cells add new cells and interior faces */
787175d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
787275d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
787375d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
787475d3a19aSMatthew G. Knepley             }
787575d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
787675d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
787775d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
787875d3a19aSMatthew G. Knepley             }
787975d3a19aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
788075d3a19aSMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
788175d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
788275d3a19aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
788375d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
788475d3a19aSMatthew G. Knepley             }
788575d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
788675d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
788775d3a19aSMatthew G. Knepley           }
788875d3a19aSMatthew G. Knepley           break;
78899b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_HEX_2D:
7890a97b51b8SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
7891a97b51b8SMatthew G. Knepley             /* Old vertices stay the same */
7892a97b51b8SMatthew G. Knepley             newp = vStartNew + (p - vStart);
7893a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7894a97b51b8SMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
7895a97b51b8SMatthew G. Knepley             /* Old interior faces add new faces and vertex */
7896a97b51b8SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
7897a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7898a97b51b8SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
7899a97b51b8SMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
7900a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7901a97b51b8SMatthew G. Knepley             }
7902a97b51b8SMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
7903a97b51b8SMatthew G. Knepley             /* Old hybrid faces stay the same */
7904a97b51b8SMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
7905a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7906a97b51b8SMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
7907a97b51b8SMatthew G. Knepley             /* Old interior cells add new cells, interior faces, and vertex */
7908a97b51b8SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
7909a97b51b8SMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
7910a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7911a97b51b8SMatthew G. Knepley             }
7912a97b51b8SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
7913a97b51b8SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
7914a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7915a97b51b8SMatthew G. Knepley             }
7916a97b51b8SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
7917a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7918a97b51b8SMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
7919a97b51b8SMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
7920a97b51b8SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
7921a97b51b8SMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
7922a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7923a97b51b8SMatthew G. Knepley             }
7924a97b51b8SMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax);
7925a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7926a97b51b8SMatthew G. Knepley           }
7927a97b51b8SMatthew G. Knepley           break;
79289b1a0e7fSLawrence Mitchell         case REFINER_SIMPLEX_3D:
7929b5da9499SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
7930b5da9499SMatthew G. Knepley             /* Old vertices stay the same */
7931b5da9499SMatthew G. Knepley             newp = vStartNew + (p - vStart);
7932b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7933b5da9499SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
7934b5da9499SMatthew G. Knepley             /* Old edges add new edges and vertex */
7935b5da9499SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
7936b5da9499SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
7937b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7938b5da9499SMatthew G. Knepley             }
7939b5da9499SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
7940b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7941b5da9499SMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
7942b5da9499SMatthew G. Knepley             /* Old faces add new faces and edges */
7943b5da9499SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
7944b5da9499SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
7945b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7946b5da9499SMatthew G. Knepley             }
7947b5da9499SMatthew G. Knepley             for (r = 0; r < 3; ++r) {
7948b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
7949b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7950b5da9499SMatthew G. Knepley             }
7951b5da9499SMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
7952b5da9499SMatthew G. Knepley             /* Old cells add new cells and interior faces and edges */
7953b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
7954b5da9499SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
7955b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7956b5da9499SMatthew G. Knepley             }
7957b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
7958b5da9499SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r;
7959b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7960b5da9499SMatthew G. Knepley             }
7961b5da9499SMatthew G. Knepley             for (r = 0; r < 1; ++r) {
7962b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r;
7963b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7964b5da9499SMatthew G. Knepley             }
7965b5da9499SMatthew G. Knepley           }
7966b5da9499SMatthew G. Knepley           break;
7967e5337592SStefano Zampini         case REFINER_SIMPLEX_TO_HEX_3D:
7968e5337592SStefano Zampini           if ((p >= vStart) && (p < vEnd)) {
7969e5337592SStefano Zampini             /* Old vertices stay the same */
7970e5337592SStefano Zampini             newp = vStartNew + (p - vStart);
7971e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7972e5337592SStefano Zampini           } else if ((p >= eStart) && (p < eEnd)) {
7973e5337592SStefano Zampini             /* Old edges add new edges and vertex */
7974e5337592SStefano Zampini             for (r = 0; r < 2; ++r) {
7975e5337592SStefano Zampini               newp = eStartNew + (p - eStart)*2 + r;
7976e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7977e5337592SStefano Zampini             }
7978e5337592SStefano Zampini             newp = vStartNew + (vEnd - vStart) + (p - eStart);
7979e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7980e5337592SStefano Zampini           } else if ((p >= fStart) && (p < fEnd)) {
7981e5337592SStefano Zampini             /* Old faces add new faces, edges and a vertex */
7982e5337592SStefano Zampini             for (r = 0; r < 3; ++r) {
7983e5337592SStefano Zampini               newp = fStartNew + (p - fStart)*3 + r;
7984e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7985e5337592SStefano Zampini             }
7986e5337592SStefano Zampini             for (r = 0; r < 3; ++r) {
7987e5337592SStefano Zampini               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
7988e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7989e5337592SStefano Zampini             }
7990e5337592SStefano Zampini           } else if ((p >= cStart) && (p < cEnd)) {
7991e5337592SStefano Zampini             /* Old cells add new cells and interior faces and edges and a vertex */
7992e5337592SStefano Zampini             for (r = 0; r < 4; ++r) {
7993e5337592SStefano Zampini               newp = cStartNew + (p - cStart)*4 + r;
7994e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7995e5337592SStefano Zampini             }
7996e5337592SStefano Zampini             for (r = 0; r < 6; ++r) {
7997e5337592SStefano Zampini               newp = fStartNew + (fEnd - fStart)*3 + (p - cStart)*6 + r;
7998e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7999e5337592SStefano Zampini             }
8000e5337592SStefano Zampini             for (r = 0; r < 4; ++r) {
8001e5337592SStefano Zampini               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*4 + r;
8002e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8003e5337592SStefano Zampini             }
8004e5337592SStefano Zampini             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + p - cStart;
8005e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8006e5337592SStefano Zampini           }
8007e5337592SStefano Zampini           break;
80089b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_SIMPLEX_3D:
80096ce3c06aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
80106ce3c06aSMatthew G. Knepley             /* Interior vertices stay the same */
80116ce3c06aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
80126ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80136ce3c06aSMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
80146ce3c06aSMatthew G. Knepley             /* Interior edges add new edges and vertex */
80156ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
80166ce3c06aSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
80176ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80186ce3c06aSMatthew G. Knepley             }
80196ce3c06aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
80206ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80216ce3c06aSMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
80226ce3c06aSMatthew G. Knepley             /* Hybrid edges stay the same */
80236ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
80246ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80256ce3c06aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
80266ce3c06aSMatthew G. Knepley             /* Interior faces add new faces and edges */
80276ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
80286ce3c06aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
80296ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80306ce3c06aSMatthew G. Knepley             }
80316ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
80326ce3c06aSMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
80336ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80346ce3c06aSMatthew G. Knepley             }
80356ce3c06aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
80366ce3c06aSMatthew G. Knepley             /* Hybrid faces add new faces and edges */
80376ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
80386ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
80396ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80406ce3c06aSMatthew G. Knepley             }
80416ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax);
80426ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80436ce3c06aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
80446ce3c06aSMatthew G. Knepley             /* Interior cells add new cells, faces, and edges */
80456ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
80466ce3c06aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
80476ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80486ce3c06aSMatthew G. Knepley             }
80496ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
80506ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
80516ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80526ce3c06aSMatthew G. Knepley             }
80536ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart);
80546ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
805558b8852aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
80566ce3c06aSMatthew G. Knepley             /* Hybrid cells add new cells and faces */
80576ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
80586ce3c06aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
80596ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80606ce3c06aSMatthew G. Knepley             }
80616ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
80626ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
80636ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80646ce3c06aSMatthew G. Knepley             }
80656ce3c06aSMatthew G. Knepley           }
80666ce3c06aSMatthew G. Knepley           break;
80679b1a0e7fSLawrence Mitchell         case REFINER_HEX_3D:
80682eabf88fSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
80692eabf88fSMatthew G. Knepley             /* Old vertices stay the same */
80702eabf88fSMatthew G. Knepley             newp = vStartNew + (p - vStart);
80712eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
807219d7d790SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
80732eabf88fSMatthew G. Knepley             /* Old edges add new edges and vertex */
80742eabf88fSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
80752eabf88fSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
80762eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80772eabf88fSMatthew G. Knepley             }
80782eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
80792eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80802eabf88fSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
80812eabf88fSMatthew G. Knepley             /* Old faces add new faces, edges, and vertex */
80822eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
80832eabf88fSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
80842eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80852eabf88fSMatthew G. Knepley             }
80862eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
80872eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r;
80882eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80892eabf88fSMatthew G. Knepley             }
80902eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart);
80912eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80922eabf88fSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
80932eabf88fSMatthew G. Knepley             /* Old cells add new cells, faces, edges, and vertex */
80942eabf88fSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
80952eabf88fSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
80962eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
80972eabf88fSMatthew G. Knepley             }
80982eabf88fSMatthew G. Knepley             for (r = 0; r < 12; ++r) {
80992eabf88fSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r;
81002eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
81012eabf88fSMatthew G. Knepley             }
81022eabf88fSMatthew G. Knepley             for (r = 0; r < 6; ++r) {
81032eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r;
81042eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
81052eabf88fSMatthew G. Knepley             }
81062eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart);
81072eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
81082eabf88fSMatthew G. Knepley           }
81092eabf88fSMatthew G. Knepley           break;
81109b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_HEX_3D:
811127fcede3SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
811227fcede3SMatthew G. Knepley             /* Interior vertices stay the same */
811327fcede3SMatthew G. Knepley             newp = vStartNew + (p - vStart);
811427fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
811527fcede3SMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
811627fcede3SMatthew G. Knepley             /* Interior edges add new edges and vertex */
811727fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
811827fcede3SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
811927fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
812027fcede3SMatthew G. Knepley             }
812127fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
812227fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
812327fcede3SMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
812427fcede3SMatthew G. Knepley             /* Hybrid edges stay the same */
812527fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax);
812627fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
812727fcede3SMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
812827fcede3SMatthew G. Knepley             /* Interior faces add new faces, edges, and vertex */
812927fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
813027fcede3SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
813127fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
813227fcede3SMatthew G. Knepley             }
813327fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
813427fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r;
813527fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
813627fcede3SMatthew G. Knepley             }
813727fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
813827fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
813927fcede3SMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
814027fcede3SMatthew G. Knepley             /* Hybrid faces add new faces and edges */
814127fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
814227fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r;
814327fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
814427fcede3SMatthew G. Knepley             }
814527fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax);
814627fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
814727fcede3SMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
814827fcede3SMatthew G. Knepley             /* Interior cells add new cells, faces, edges, and vertex */
814927fcede3SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
815027fcede3SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
815127fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
815227fcede3SMatthew G. Knepley             }
815327fcede3SMatthew G. Knepley             for (r = 0; r < 12; ++r) {
815427fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r;
815527fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
815627fcede3SMatthew G. Knepley             }
815727fcede3SMatthew G. Knepley             for (r = 0; r < 6; ++r) {
815827fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r;
815927fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
816027fcede3SMatthew G. Knepley             }
816127fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart);
816227fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
816327fcede3SMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
816427fcede3SMatthew G. Knepley             /* Hybrid cells add new cells, faces, and edges */
816527fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
816627fcede3SMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
816727fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
816827fcede3SMatthew G. Knepley             }
816927fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
817027fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r;
817127fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
817227fcede3SMatthew G. Knepley             }
817327fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax);
817427fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
817527fcede3SMatthew G. Knepley           }
817627fcede3SMatthew G. Knepley           break;
817775d3a19aSMatthew G. Knepley         default:
817875d3a19aSMatthew G. Knepley           SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
817975d3a19aSMatthew G. Knepley         }
818075d3a19aSMatthew G. Knepley       }
818175d3a19aSMatthew G. Knepley       ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr);
818275d3a19aSMatthew G. Knepley       ierr = ISDestroy(&pointIS);CHKERRQ(ierr);
818375d3a19aSMatthew G. Knepley     }
818475d3a19aSMatthew G. Knepley     ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr);
818575d3a19aSMatthew G. Knepley     ierr = ISDestroy(&valueIS);CHKERRQ(ierr);
818675d3a19aSMatthew G. Knepley     if (0) {
818775d3a19aSMatthew G. Knepley       ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
818875d3a19aSMatthew G. Knepley     }
818975d3a19aSMatthew G. Knepley   }
819075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
819175d3a19aSMatthew G. Knepley }
819275d3a19aSMatthew G. Knepley 
819375d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */
8194509c9b89SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined)
819575d3a19aSMatthew G. Knepley {
819675d3a19aSMatthew G. Knepley   DM             rdm;
819775d3a19aSMatthew G. Knepley   PetscInt      *depthSize;
819875d3a19aSMatthew G. Knepley   PetscInt       dim, depth = 0, d, pStart = 0, pEnd = 0;
819975d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
820075d3a19aSMatthew G. Knepley 
820175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
820275d3a19aSMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr);
820375d3a19aSMatthew G. Knepley   ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr);
8204c73cfb54SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
8205c73cfb54SMatthew G. Knepley   ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr);
820675d3a19aSMatthew G. Knepley   /* Calculate number of new points of each depth */
820775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
82081e573d11SMatthew G. Knepley   if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement");
8209854ce69bSBarry Smith   ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr);
821075d3a19aSMatthew G. Knepley   ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr);
821175d3a19aSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
821275d3a19aSMatthew G. Knepley   /* Step 1: Set chart */
821375d3a19aSMatthew G. Knepley   for (d = 0; d <= depth; ++d) pEnd += depthSize[d];
821475d3a19aSMatthew G. Knepley   ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr);
821575d3a19aSMatthew G. Knepley   /* Step 2: Set cone/support sizes */
821675d3a19aSMatthew G. Knepley   ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
821775d3a19aSMatthew G. Knepley   /* Step 3: Setup refined DM */
821875d3a19aSMatthew G. Knepley   ierr = DMSetUp(rdm);CHKERRQ(ierr);
821975d3a19aSMatthew G. Knepley   /* Step 4: Set cones and supports */
822075d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
822175d3a19aSMatthew G. Knepley   /* Step 5: Stratify */
822275d3a19aSMatthew G. Knepley   ierr = DMPlexStratify(rdm);CHKERRQ(ierr);
82230fadad52SMatthew G. Knepley   /* Step 6: Create pointSF */
822475d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
822590b157c4SStefano Zampini   /* Step 7: Create labels */
822675d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
822790b157c4SStefano Zampini   /* Step 8: Set coordinates */
822890b157c4SStefano Zampini   ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
822975d3a19aSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
823075d3a19aSMatthew G. Knepley 
823175d3a19aSMatthew G. Knepley   *dmRefined = rdm;
823275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
823375d3a19aSMatthew G. Knepley }
823475d3a19aSMatthew G. Knepley 
82352389894bSMatthew G. Knepley /*@
82362389894bSMatthew G. Knepley   DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data
82372389894bSMatthew G. Knepley 
82382389894bSMatthew G. Knepley   Input Parameter:
82392389894bSMatthew G. Knepley . dm - The coarse DM
82402389894bSMatthew G. Knepley 
82412389894bSMatthew G. Knepley   Output Parameter:
82422389894bSMatthew G. Knepley . fpointIS - The IS of all the fine points which exist in the original coarse mesh
82432389894bSMatthew G. Knepley 
82442389894bSMatthew G. Knepley   Level: developer
82452389894bSMatthew G. Knepley 
82462389894bSMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS()
82472389894bSMatthew G. Knepley @*/
82482389894bSMatthew G. Knepley PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS)
82492389894bSMatthew G. Knepley {
82502389894bSMatthew G. Knepley   CellRefiner    cellRefiner;
82512389894bSMatthew G. Knepley   PetscInt      *depthSize, *fpoints;
82522389894bSMatthew G. Knepley   PetscInt       cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
82532389894bSMatthew G. Knepley   PetscInt       depth, pStart, pEnd, p, vStart, vEnd, v;
82542389894bSMatthew G. Knepley   PetscErrorCode ierr;
82552389894bSMatthew G. Knepley 
82562389894bSMatthew G. Knepley   PetscFunctionBegin;
82572389894bSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
82582389894bSMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
82592389894bSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
82602389894bSMatthew G. Knepley   ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr);
8261854ce69bSBarry Smith   ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr);
82622389894bSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
82632389894bSMatthew G. Knepley   if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
82642389894bSMatthew G. Knepley   ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr);
82652389894bSMatthew G. Knepley   for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1;
82662389894bSMatthew G. Knepley   switch (cellRefiner) {
82676c0c04f5SMatthew G. Knepley   case REFINER_SIMPLEX_1D:
82686c0c04f5SMatthew G. Knepley   case REFINER_SIMPLEX_2D:
82696c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_SIMPLEX_2D:
82706c0c04f5SMatthew G. Knepley   case REFINER_HEX_2D:
82716c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_HEX_2D:
82726c0c04f5SMatthew G. Knepley   case REFINER_SIMPLEX_3D:
82736c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_SIMPLEX_3D:
82746c0c04f5SMatthew G. Knepley   case REFINER_HEX_3D:
82756c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_HEX_3D:
82762389894bSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart);
82772389894bSMatthew G. Knepley     break;
82782389894bSMatthew G. Knepley   default:
82792389894bSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", cellRefiner);
82802389894bSMatthew G. Knepley   }
82812389894bSMatthew G. Knepley   ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr);
82822389894bSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
82832389894bSMatthew G. Knepley   PetscFunctionReturn(0);
82842389894bSMatthew G. Knepley }
82852389894bSMatthew G. Knepley 
82860e2b6761SMatthew G. Knepley /*@
82870e2b6761SMatthew G. Knepley   DMPlexSetRefinementUniform - Set the flag for uniform refinement
82880e2b6761SMatthew G. Knepley 
82890e2b6761SMatthew G. Knepley   Input Parameters:
82900e2b6761SMatthew G. Knepley + dm - The DM
82910e2b6761SMatthew G. Knepley - refinementUniform - The flag for uniform refinement
82920e2b6761SMatthew G. Knepley 
82930e2b6761SMatthew G. Knepley   Level: developer
82940e2b6761SMatthew G. Knepley 
82950e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
82960e2b6761SMatthew G. Knepley @*/
829775d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
829875d3a19aSMatthew G. Knepley {
829975d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
830075d3a19aSMatthew G. Knepley 
830175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
830275d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
830375d3a19aSMatthew G. Knepley   mesh->refinementUniform = refinementUniform;
830475d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
830575d3a19aSMatthew G. Knepley }
830675d3a19aSMatthew G. Knepley 
83070e2b6761SMatthew G. Knepley /*@
83080e2b6761SMatthew G. Knepley   DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement
83090e2b6761SMatthew G. Knepley 
83100e2b6761SMatthew G. Knepley   Input Parameter:
83110e2b6761SMatthew G. Knepley . dm - The DM
83120e2b6761SMatthew G. Knepley 
83130e2b6761SMatthew G. Knepley   Output Parameter:
83140e2b6761SMatthew G. Knepley . refinementUniform - The flag for uniform refinement
83150e2b6761SMatthew G. Knepley 
83160e2b6761SMatthew G. Knepley   Level: developer
83170e2b6761SMatthew G. Knepley 
83180e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
83190e2b6761SMatthew G. Knepley @*/
832075d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
832175d3a19aSMatthew G. Knepley {
832275d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
832375d3a19aSMatthew G. Knepley 
832475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
832575d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
832675d3a19aSMatthew G. Knepley   PetscValidPointer(refinementUniform,  2);
832775d3a19aSMatthew G. Knepley   *refinementUniform = mesh->refinementUniform;
832875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
832975d3a19aSMatthew G. Knepley }
833075d3a19aSMatthew G. Knepley 
83310e2b6761SMatthew G. Knepley /*@
83320e2b6761SMatthew G. Knepley   DMPlexSetRefinementLimit - Set the maximum cell volume for refinement
83330e2b6761SMatthew G. Knepley 
83340e2b6761SMatthew G. Knepley   Input Parameters:
83350e2b6761SMatthew G. Knepley + dm - The DM
83360e2b6761SMatthew G. Knepley - refinementLimit - The maximum cell volume in the refined mesh
83370e2b6761SMatthew G. Knepley 
83380e2b6761SMatthew G. Knepley   Level: developer
83390e2b6761SMatthew G. Knepley 
83400e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
83410e2b6761SMatthew G. Knepley @*/
834275d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
834375d3a19aSMatthew G. Knepley {
834475d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
834575d3a19aSMatthew G. Knepley 
834675d3a19aSMatthew G. Knepley   PetscFunctionBegin;
834775d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
834875d3a19aSMatthew G. Knepley   mesh->refinementLimit = refinementLimit;
834975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
835075d3a19aSMatthew G. Knepley }
835175d3a19aSMatthew G. Knepley 
83520e2b6761SMatthew G. Knepley /*@
83530e2b6761SMatthew G. Knepley   DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement
83540e2b6761SMatthew G. Knepley 
83550e2b6761SMatthew G. Knepley   Input Parameter:
83560e2b6761SMatthew G. Knepley . dm - The DM
83570e2b6761SMatthew G. Knepley 
83580e2b6761SMatthew G. Knepley   Output Parameter:
83590e2b6761SMatthew G. Knepley . refinementLimit - The maximum cell volume in the refined mesh
83600e2b6761SMatthew G. Knepley 
83610e2b6761SMatthew G. Knepley   Level: developer
83620e2b6761SMatthew G. Knepley 
83630e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
83640e2b6761SMatthew G. Knepley @*/
836575d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
836675d3a19aSMatthew G. Knepley {
836775d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
836875d3a19aSMatthew G. Knepley 
836975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
837075d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
837175d3a19aSMatthew G. Knepley   PetscValidPointer(refinementLimit,  2);
837275d3a19aSMatthew G. Knepley   /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
837375d3a19aSMatthew G. Knepley   *refinementLimit = mesh->refinementLimit;
837475d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
837575d3a19aSMatthew G. Knepley }
837675d3a19aSMatthew G. Knepley 
8377b28003e6SMatthew G. Knepley /*@
8378b28003e6SMatthew G. Knepley   DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement
8379b28003e6SMatthew G. Knepley 
8380b28003e6SMatthew G. Knepley   Input Parameters:
8381b28003e6SMatthew G. Knepley + dm - The DM
8382b28003e6SMatthew G. Knepley - refinementFunc - Function giving the maximum cell volume in the refined mesh
8383b28003e6SMatthew G. Knepley 
8384b28003e6SMatthew G. Knepley   Note: The calling sequence is refinementFunc(coords, limit)
8385b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid
8386b28003e6SMatthew G. Knepley $ limit  - The maximum cell volume for a cell containing this point
8387b28003e6SMatthew G. Knepley 
8388b28003e6SMatthew G. Knepley   Level: developer
8389b28003e6SMatthew G. Knepley 
8390b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
8391b28003e6SMatthew G. Knepley @*/
8392b28003e6SMatthew G. Knepley PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *))
8393b28003e6SMatthew G. Knepley {
8394b28003e6SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
8395b28003e6SMatthew G. Knepley 
8396b28003e6SMatthew G. Knepley   PetscFunctionBegin;
8397b28003e6SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8398b28003e6SMatthew G. Knepley   mesh->refinementFunc = refinementFunc;
8399b28003e6SMatthew G. Knepley   PetscFunctionReturn(0);
8400b28003e6SMatthew G. Knepley }
8401b28003e6SMatthew G. Knepley 
8402b28003e6SMatthew G. Knepley /*@
8403b28003e6SMatthew G. Knepley   DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement
8404b28003e6SMatthew G. Knepley 
8405b28003e6SMatthew G. Knepley   Input Parameter:
8406b28003e6SMatthew G. Knepley . dm - The DM
8407b28003e6SMatthew G. Knepley 
8408b28003e6SMatthew G. Knepley   Output Parameter:
8409b28003e6SMatthew G. Knepley . refinementFunc - Function giving the maximum cell volume in the refined mesh
8410b28003e6SMatthew G. Knepley 
8411b28003e6SMatthew G. Knepley   Note: The calling sequence is refinementFunc(coords, limit)
8412b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid
8413b28003e6SMatthew G. Knepley $ limit  - The maximum cell volume for a cell containing this point
8414b28003e6SMatthew G. Knepley 
8415b28003e6SMatthew G. Knepley   Level: developer
8416b28003e6SMatthew G. Knepley 
8417b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
8418b28003e6SMatthew G. Knepley @*/
8419b28003e6SMatthew G. Knepley PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *))
8420b28003e6SMatthew G. Knepley {
8421b28003e6SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
8422b28003e6SMatthew G. Knepley 
8423b28003e6SMatthew G. Knepley   PetscFunctionBegin;
8424b28003e6SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8425b28003e6SMatthew G. Knepley   PetscValidPointer(refinementFunc,  2);
8426b28003e6SMatthew G. Knepley   *refinementFunc = mesh->refinementFunc;
8427b28003e6SMatthew G. Knepley   PetscFunctionReturn(0);
8428b28003e6SMatthew G. Knepley }
8429b28003e6SMatthew G. Knepley 
8430509c9b89SMatthew G. Knepley PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner)
843175d3a19aSMatthew G. Knepley {
84320f9259d6SMatthew G. Knepley   PetscInt       dim, cStart, cEnd, coneSize, cMax, fMax;
843375d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
843475d3a19aSMatthew G. Knepley 
843575d3a19aSMatthew G. Knepley   PetscFunctionBegin;
8436c73cfb54SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
84373478d7aaSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
84389b1a0e7fSLawrence Mitchell   if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; PetscFunctionReturn(0);}
843975d3a19aSMatthew G. Knepley   ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr);
844089b38ed4SMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, NULL, NULL);CHKERRQ(ierr);
844175d3a19aSMatthew G. Knepley   switch (dim) {
84420314a74cSLawrence Mitchell   case 1:
84430314a74cSLawrence Mitchell     switch (coneSize) {
84440314a74cSLawrence Mitchell     case 2:
84450314a74cSLawrence Mitchell       *cellRefiner = REFINER_SIMPLEX_1D;
84460314a74cSLawrence Mitchell       break;
84470314a74cSLawrence Mitchell     default:
84480314a74cSLawrence Mitchell       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
84490314a74cSLawrence Mitchell     }
84500314a74cSLawrence Mitchell     break;
845175d3a19aSMatthew G. Knepley   case 2:
845275d3a19aSMatthew G. Knepley     switch (coneSize) {
845375d3a19aSMatthew G. Knepley     case 3:
84549b1a0e7fSLawrence Mitchell       if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_2D;
84559b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_SIMPLEX_2D;
845675d3a19aSMatthew G. Knepley       break;
845775d3a19aSMatthew G. Knepley     case 4:
845889b38ed4SMatthew G. Knepley       if (cMax >= 0 && fMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_2D;
84599b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_HEX_2D;
846075d3a19aSMatthew G. Knepley       break;
846175d3a19aSMatthew G. Knepley     default:
846275d3a19aSMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
846375d3a19aSMatthew G. Knepley     }
846475d3a19aSMatthew G. Knepley     break;
8465b5da9499SMatthew G. Knepley   case 3:
8466b5da9499SMatthew G. Knepley     switch (coneSize) {
8467b5da9499SMatthew G. Knepley     case 4:
84689b1a0e7fSLawrence Mitchell       if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D;
84699b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_SIMPLEX_3D;
8470b5da9499SMatthew G. Knepley       break;
84712eabf88fSMatthew G. Knepley     case 6:
84729b1a0e7fSLawrence Mitchell       if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_3D;
84739b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_HEX_3D;
84742eabf88fSMatthew G. Knepley       break;
8475b5da9499SMatthew G. Knepley     default:
8476b5da9499SMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
8477b5da9499SMatthew G. Knepley     }
8478b5da9499SMatthew G. Knepley     break;
847975d3a19aSMatthew G. Knepley   default:
848075d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim);
848175d3a19aSMatthew G. Knepley   }
848275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
848375d3a19aSMatthew G. Knepley }
84840d1cd5e0SMatthew G. Knepley 
84850d1cd5e0SMatthew G. Knepley PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined)
84860d1cd5e0SMatthew G. Knepley {
84870d1cd5e0SMatthew G. Knepley   PetscBool      isUniform, localized;
84880d1cd5e0SMatthew G. Knepley   PetscErrorCode ierr;
84890d1cd5e0SMatthew G. Knepley 
84900d1cd5e0SMatthew G. Knepley   PetscFunctionBegin;
84910d1cd5e0SMatthew G. Knepley   ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr);
84920d1cd5e0SMatthew G. Knepley   ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr);
84930d1cd5e0SMatthew G. Knepley   if (isUniform) {
84940d1cd5e0SMatthew G. Knepley     CellRefiner cellRefiner;
84950d1cd5e0SMatthew G. Knepley 
84960d1cd5e0SMatthew G. Knepley     ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr);
84970d1cd5e0SMatthew G. Knepley     ierr = DMPlexRefineUniform_Internal(dm, cellRefiner, dmRefined);CHKERRQ(ierr);
84980d1cd5e0SMatthew G. Knepley     ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr);
84990d1cd5e0SMatthew G. Knepley     if (localized) {ierr = DMLocalizeCoordinates(*dmRefined);CHKERRQ(ierr);}
85000d1cd5e0SMatthew G. Knepley   } else {
85010d1cd5e0SMatthew G. Knepley     ierr = DMPlexRefine_Internal(dm, NULL, dmRefined);CHKERRQ(ierr);
85020d1cd5e0SMatthew G. Knepley   }
85030d1cd5e0SMatthew G. Knepley   PetscFunctionReturn(0);
85040d1cd5e0SMatthew G. Knepley }
85050d1cd5e0SMatthew G. Knepley 
85060d1cd5e0SMatthew G. Knepley PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[])
85070d1cd5e0SMatthew G. Knepley {
85080d1cd5e0SMatthew G. Knepley   DM             cdm = dm;
85090d1cd5e0SMatthew G. Knepley   PetscInt       r;
85100d1cd5e0SMatthew G. Knepley   PetscBool      isUniform, localized;
85110d1cd5e0SMatthew G. Knepley   PetscErrorCode ierr;
85120d1cd5e0SMatthew G. Knepley 
85130d1cd5e0SMatthew G. Knepley   PetscFunctionBegin;
85140d1cd5e0SMatthew G. Knepley   ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr);
85150d1cd5e0SMatthew G. Knepley   ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr);
85160d1cd5e0SMatthew G. Knepley   if (isUniform) {
85170d1cd5e0SMatthew G. Knepley     for (r = 0; r < nlevels; ++r) {
85180d1cd5e0SMatthew G. Knepley       CellRefiner cellRefiner;
85190d1cd5e0SMatthew G. Knepley 
85200d1cd5e0SMatthew G. Knepley       ierr = DMPlexGetCellRefiner_Internal(cdm, &cellRefiner);CHKERRQ(ierr);
85210d1cd5e0SMatthew G. Knepley       ierr = DMPlexRefineUniform_Internal(cdm, cellRefiner, &dmRefined[r]);CHKERRQ(ierr);
85220d1cd5e0SMatthew G. Knepley       ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr);
85230d1cd5e0SMatthew G. Knepley       if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);}
85240d1cd5e0SMatthew G. Knepley       ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr);
85250d1cd5e0SMatthew G. Knepley       ierr = DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);CHKERRQ(ierr);
85260d1cd5e0SMatthew G. Knepley       cdm  = dmRefined[r];
85270d1cd5e0SMatthew G. Knepley     }
85280d1cd5e0SMatthew G. Knepley   } else {
85290d1cd5e0SMatthew G. Knepley     for (r = 0; r < nlevels; ++r) {
85300d1cd5e0SMatthew G. Knepley       ierr = DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);CHKERRQ(ierr);
85310d1cd5e0SMatthew G. Knepley       ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr);
85320d1cd5e0SMatthew G. Knepley       if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);}
85330d1cd5e0SMatthew G. Knepley       ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr);
85340d1cd5e0SMatthew G. Knepley       cdm  = dmRefined[r];
85350d1cd5e0SMatthew G. Knepley     }
85360d1cd5e0SMatthew G. Knepley   }
85370d1cd5e0SMatthew G. Knepley   PetscFunctionReturn(0);
85380d1cd5e0SMatthew G. Knepley }
8539