xref: /petsc/src/dm/impls/plex/plexrefine.c (revision d918548ef4469c28d9d6b794d127f2accc0534ff)
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;
114c1879b55SMatthew G. Knepley   case REFINER_HEX_3D:
115c1879b55SMatthew G. Knepley     /*
116c1879b55SMatthew G. Knepley      Bottom (viewed from top)    Top
117c1879b55SMatthew G. Knepley      1---------2---------2       7---------2---------6
118c1879b55SMatthew G. Knepley      |         |         |       |         |         |
119c1879b55SMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
120c1879b55SMatthew G. Knepley      |         |         |       |         |         |
121c1879b55SMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
122c1879b55SMatthew G. Knepley      |         |         |       |         |         |
123c1879b55SMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
124c1879b55SMatthew G. Knepley      |         |         |       |         |         |
125c1879b55SMatthew G. Knepley      0---------0---------3       4---------0---------5
126c1879b55SMatthew G. Knepley      */
127c1879b55SMatthew G. Knepley     break;
128c1879b55SMatthew G. Knepley     dim = 3;
129c1879b55SMatthew G. Knepley     if (numSubcells) *numSubcells = 8;
130c1879b55SMatthew G. Knepley     if (v0) {
131c1879b55SMatthew G. Knepley       ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr);
132c1879b55SMatthew G. Knepley       /* A */
133c1879b55SMatthew G. Knepley       v[0+0] = -1.0; v[0+1] = -1.0; v[0+2] = -1.0;
134c1879b55SMatthew G. Knepley       j[0+0] =  0.5; j[0+1] =  0.0; j[0+2] =  0.0;
135c1879b55SMatthew G. Knepley       j[0+3] =  0.0; j[0+4] =  0.5; j[0+5] =  0.0;
136c1879b55SMatthew G. Knepley       j[0+6] =  0.0; j[0+7] =  0.0; j[0+8] =  0.5;
137c1879b55SMatthew G. Knepley       /* B */
138c1879b55SMatthew G. Knepley       v[3+0] = -1.0; v[3+1] =  0.0; v[3+2] = -1.0;
139c1879b55SMatthew G. Knepley       j[9+0] =  0.5; j[9+1] =  0.0; j[9+2] =  0.0;
140c1879b55SMatthew G. Knepley       j[9+3] =  0.0; j[9+4] =  0.5; j[9+5] =  0.0;
141c1879b55SMatthew G. Knepley       j[9+6] =  0.0; j[9+7] =  0.0; j[9+8] =  0.5;
142c1879b55SMatthew G. Knepley       /* C */
143c1879b55SMatthew G. Knepley       v[6+0] =  0.0; v[6+1] =  0.0; v[6+2] = -1.0;
144c1879b55SMatthew G. Knepley       j[18+0] = 0.5; j[18+1] = 0.0; j[18+2] = 0.0;
145c1879b55SMatthew G. Knepley       j[18+3] = 0.0; j[18+4] = 0.5; j[18+5] = 0.0;
146c1879b55SMatthew G. Knepley       j[18+6] = 0.0; j[18+7] = 0.0; j[18+8] = 0.5;
147c1879b55SMatthew G. Knepley       /* D */
148c1879b55SMatthew G. Knepley       v[9+0] =  0.0; v[9+1] = -1.0; v[9+2] = -1.0;
149c1879b55SMatthew G. Knepley       j[27+0] = 0.5; j[27+1] = 0.0; j[27+2] = 0.0;
150c1879b55SMatthew G. Knepley       j[27+3] = 0.0; j[27+4] = 0.5; j[27+5] = 0.0;
151c1879b55SMatthew G. Knepley       j[27+6] = 0.0; j[27+7] = 0.0; j[27+8] = 0.5;
152c1879b55SMatthew G. Knepley       /* E */
153c1879b55SMatthew G. Knepley       v[12+0] = -1.0; v[12+1] = -1.0; v[12+2] =  0.0;
154c1879b55SMatthew G. Knepley       j[36+0] =  0.5; j[36+1] =  0.0; j[36+2] =  0.0;
155c1879b55SMatthew G. Knepley       j[36+3] =  0.0; j[36+4] =  0.5; j[36+5] =  0.0;
156c1879b55SMatthew G. Knepley       j[36+6] =  0.0; j[36+7] =  0.0; j[36+8] =  0.5;
157c1879b55SMatthew G. Knepley       /* F */
158c1879b55SMatthew G. Knepley       v[15+0] =  0.0; v[15+1] = -1.0; v[15+2] =  0.0;
159c1879b55SMatthew G. Knepley       j[45+0] =  0.5; j[45+1] =  0.0; j[45+2] =  0.0;
160c1879b55SMatthew G. Knepley       j[45+3] =  0.0; j[45+4] =  0.5; j[45+5] =  0.0;
161c1879b55SMatthew G. Knepley       j[45+6] =  0.0; j[45+7] =  0.0; j[45+8] =  0.5;
162c1879b55SMatthew G. Knepley       /* G */
163c1879b55SMatthew G. Knepley       v[18+0] =  0.0; v[18+1] =  0.0; v[18+2] =  0.0;
164c1879b55SMatthew G. Knepley       j[54+0] =  0.5; j[54+1] =  0.0; j[54+2] =  0.0;
165c1879b55SMatthew G. Knepley       j[54+3] =  0.0; j[54+4] =  0.5; j[54+5] =  0.0;
166c1879b55SMatthew G. Knepley       j[54+6] =  0.0; j[54+7] =  0.0; j[54+8] =  0.5;
167c1879b55SMatthew G. Knepley       /* H */
168c1879b55SMatthew G. Knepley       v[21+0] = -1.0; v[21+1] =  0.0; v[21+2] =  0.0;
169c1879b55SMatthew G. Knepley       j[63+0] =  0.5; j[63+1] =  0.0; j[63+2] =  0.0;
170c1879b55SMatthew G. Knepley       j[63+3] =  0.0; j[63+4] =  0.5; j[63+5] =  0.0;
171c1879b55SMatthew G. Knepley       j[63+6] =  0.0; j[63+7] =  0.0; j[63+8] =  0.5;
172c1879b55SMatthew G. Knepley       for (s = 0; s < 8; ++s) {
173c1879b55SMatthew G. Knepley         DMPlex_Det3D_Internal(&detJ, &j[s*dim*dim]);
174c1879b55SMatthew G. Knepley         DMPlex_Invert3D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ);
175c1879b55SMatthew G. Knepley       }
176c1879b55SMatthew G. Knepley     }
177bed052eaSMatthew G. Knepley   default:
178bed052eaSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
179bed052eaSMatthew G. Knepley   }
180bed052eaSMatthew G. Knepley   if (v0) {*v0 = v; *jac = j; *invjac = invj;}
181bed052eaSMatthew G. Knepley   PetscFunctionReturn(0);
182bed052eaSMatthew G. Knepley }
183bed052eaSMatthew G. Knepley 
184bed052eaSMatthew G. Knepley PetscErrorCode CellRefinerRestoreAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[])
185bed052eaSMatthew G. Knepley {
186bed052eaSMatthew G. Knepley   PetscErrorCode ierr;
187bed052eaSMatthew G. Knepley 
188bed052eaSMatthew G. Knepley   PetscFunctionBegin;
189bed052eaSMatthew G. Knepley   ierr = PetscFree3(*v0,*jac,*invjac);CHKERRQ(ierr);
190bed052eaSMatthew G. Knepley   PetscFunctionReturn(0);
191bed052eaSMatthew G. Knepley }
192bed052eaSMatthew G. Knepley 
19380389061SMatthew G. Knepley /* Should this be here or in the DualSpace somehow? */
19480389061SMatthew G. Knepley PetscErrorCode CellRefinerInCellTest_Internal(CellRefiner refiner, const PetscReal point[], PetscBool *inside)
19580389061SMatthew G. Knepley {
19680389061SMatthew G. Knepley   PetscReal sum = 0.0;
19780389061SMatthew G. Knepley   PetscInt  d;
19880389061SMatthew G. Knepley 
19980389061SMatthew G. Knepley   PetscFunctionBegin;
20080389061SMatthew G. Knepley   *inside = PETSC_TRUE;
20180389061SMatthew G. Knepley   switch (refiner) {
2029b1a0e7fSLawrence Mitchell   case REFINER_NOOP: break;
2036c0c04f5SMatthew G. Knepley   case REFINER_SIMPLEX_2D:
20480389061SMatthew G. Knepley     for (d = 0; d < 2; ++d) {
20580389061SMatthew G. Knepley       if (point[d] < -1.0) {*inside = PETSC_FALSE; break;}
20680389061SMatthew G. Knepley       sum += point[d];
20780389061SMatthew G. Knepley     }
20824c234d2SMatthew G. Knepley     if (sum > 1.0e-10) {*inside = PETSC_FALSE; break;}
20980389061SMatthew G. Knepley     break;
2106c0c04f5SMatthew G. Knepley   case REFINER_HEX_2D:
21124c234d2SMatthew G. Knepley     for (d = 0; d < 2; ++d) if ((point[d] < -1.00000000001) || (point[d] > 1.000000000001)) {*inside = PETSC_FALSE; break;}
21280389061SMatthew G. Knepley     break;
21380389061SMatthew G. Knepley   default:
21480389061SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
21580389061SMatthew G. Knepley   }
21680389061SMatthew G. Knepley   PetscFunctionReturn(0);
21780389061SMatthew G. Knepley }
21880389061SMatthew G. Knepley 
21986150812SJed Brown static PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[])
22075d3a19aSMatthew G. Knepley {
2216ce3c06aSMatthew G. Knepley   PetscInt       cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax;
22275d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
22375d3a19aSMatthew G. Knepley 
22475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
22575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
22675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
22775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
22875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
22975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
23075d3a19aSMatthew G. Knepley   switch (refiner) {
2319b1a0e7fSLawrence Mitchell   case REFINER_NOOP:
2323478d7aaSMatthew G. Knepley     break;
2330314a74cSLawrence Mitchell   case REFINER_SIMPLEX_1D:
2340314a74cSLawrence Mitchell     depthSize[0] = vEnd - vStart + cEnd - cStart;         /* Add a vertex on every cell. */
2350314a74cSLawrence Mitchell     depthSize[1] = 2*(cEnd - cStart);                     /* Split every cell in 2. */
2360314a74cSLawrence Mitchell     break;
2379b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
23875d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fEnd - fStart;         /* Add a vertex on every face */
23975d3a19aSMatthew 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 */
24075d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cEnd - cStart);                     /* Every cell split into 4 cells */
24175d3a19aSMatthew G. Knepley     break;
2429b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
24375d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
24475d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
24575d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fMax - fStart;                                         /* Add a vertex on every face, but not hybrid faces */
24675d3a19aSMatthew 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 */
24775d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax);                                   /* Interior cells split into 4 cells, Hybrid cells split into 2 cells */
24875d3a19aSMatthew G. Knepley     break;
249e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_2D:
250e5337592SStefano Zampini     depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */
251e5337592SStefano Zampini     depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart);         /* Every face is split into 2 faces and 3 faces are added for each cell */
252e5337592SStefano Zampini     depthSize[2] = 3*(cEnd - cStart);                             /* Every cell split into 3 cells */
253e5337592SStefano Zampini     break;
2549b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
255149f48fdSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */
25675d3a19aSMatthew 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 */
25775d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cEnd - cStart);                             /* Every cell split into 4 cells */
25875d3a19aSMatthew G. Knepley     break;
2599b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
260a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
261a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
262a97b51b8SMatthew G. Knepley     /* Quadrilateral */
263a97b51b8SMatthew G. Knepley     depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart;                 /* Add a vertex on every face and cell */
264a97b51b8SMatthew 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 */
265a97b51b8SMatthew G. Knepley     depthSize[2] = 4*(cMax - cStart);                                             /* Every cell split into 4 cells */
266a97b51b8SMatthew G. Knepley     /* Segment Prisms */
267a97b51b8SMatthew G. Knepley     depthSize[0] += 0;                                                            /* No hybrid vertices */
268a97b51b8SMatthew G. Knepley     depthSize[1] +=   (fEnd - fMax)  +   (cEnd - cMax);                           /* Every hybrid face remains and 1 faces is added for each hybrid cell */
269a97b51b8SMatthew G. Knepley     depthSize[2] += 2*(cEnd - cMax);                                              /* Every hybrid cell split into 2 cells */
270a97b51b8SMatthew G. Knepley     break;
2719b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
272b5da9499SMatthew G. Knepley     depthSize[0] =    vEnd - vStart  +    eEnd - eStart;                    /* Add a vertex on every edge */
273b5da9499SMatthew 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 */
274b5da9499SMatthew G. Knepley     depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart);                   /* Every face split into 4 faces and 8 faces are added for each cell */
275b5da9499SMatthew G. Knepley     depthSize[3] = 8*(cEnd - cStart);                                       /* Every cell split into 8 cells */
276b5da9499SMatthew G. Knepley     break;
2779b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
278b5da9499SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
2796ce3c06aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
280b5da9499SMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
281dae4404aSMatthew G. Knepley     /* Tetrahedra */
282dae4404aSMatthew G. Knepley     depthSize[0]  =    vEnd - vStart  +    eMax - eStart;                    /* Add a vertex on every interior edge */
283dae4404aSMatthew 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 */
284dae4404aSMatthew G. Knepley     depthSize[2]  = 4*(fMax - fStart) + 8*(cMax - cStart);                   /* Every interior face split into 4 faces, 8 faces added for each interior cell */
285dae4404aSMatthew G. Knepley     depthSize[3]  = 8*(cMax - cStart);                                       /* Every interior cell split into 8 cells */
286dae4404aSMatthew G. Knepley     /* Triangular Prisms */
287dae4404aSMatthew G. Knepley     depthSize[0] += 0;                                                       /* No hybrid vertices */
288dae4404aSMatthew G. Knepley     depthSize[1] +=   (eEnd - eMax)   +   (fEnd - fMax);                     /* Every hybrid edge remains, 1 edge for every hybrid face */
2896ce3c06aSMatthew 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 */
290dae4404aSMatthew G. Knepley     depthSize[3] += 4*(cEnd - cMax);                                         /* Every hybrid cell split into 4 cells */
291b5da9499SMatthew G. Knepley     break;
292e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_3D:
293e5337592SStefano Zampini     depthSize[0] = vEnd - vStart + fEnd - fStart + eEnd - eStart + cEnd - cStart; /* Add a vertex on every face, edge and cell */
294e5337592SStefano 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 */
295e5337592SStefano Zampini     depthSize[2] = 3*(fEnd - fStart) + 6*(cEnd - cStart);                         /* Every face is split into 3 faces and 6 faces are added for each cell */
296e5337592SStefano Zampini     depthSize[3] = 4*(cEnd - cStart);                                             /* Every cell split into 4 cells */
297e5337592SStefano Zampini     break;
2989b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
2996ce3c06aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */
3006ce3c06aSMatthew 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 */
3016ce3c06aSMatthew 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 */
3026ce3c06aSMatthew G. Knepley     depthSize[3] = 8*(cEnd - cStart);                                             /* Every cell split into 8 cells */
3036ce3c06aSMatthew G. Knepley     break;
3049b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
30527fcede3SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
30627fcede3SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
30727fcede3SMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
30827fcede3SMatthew G. Knepley     /* Hexahedra */
30927fcede3SMatthew G. Knepley     depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */
31027fcede3SMatthew 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 */
31127fcede3SMatthew 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 */
31227fcede3SMatthew G. Knepley     depthSize[3] = 8*(cMax - cStart);                                             /* Every cell split into 8 cells */
31327fcede3SMatthew G. Knepley     /* Quadrilateral Prisms */
31427fcede3SMatthew G. Knepley     depthSize[0] += 0;                                                            /* No hybrid vertices */
31527fcede3SMatthew G. Knepley     depthSize[1] +=   (eEnd - eMax)   +   (fEnd - fMax)   +   (cEnd - cMax);      /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */
31627fcede3SMatthew 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 */
31727fcede3SMatthew G. Knepley     depthSize[3] += 4*(cEnd - cMax);                                              /* Every hybrid cell split into 4 cells */
31827fcede3SMatthew G. Knepley     break;
31975d3a19aSMatthew G. Knepley   default:
32075d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
32175d3a19aSMatthew G. Knepley   }
32275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
32375d3a19aSMatthew G. Knepley }
32475d3a19aSMatthew G. Knepley 
32542525629SMatthew G. Knepley /* Return triangle edge for orientation o, if it is r for o == 0 */
32642525629SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) {
327518a8359SMatthew G. Knepley   return (o < 0 ? 2-(o+r) : o+r)%3;
328518a8359SMatthew G. Knepley }
329de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) {
330de65f515SMatthew G. Knepley   return (o < 0 ? 2-(o+s) : 3+s-o)%3;
331de65f515SMatthew G. Knepley }
332518a8359SMatthew G. Knepley 
333518a8359SMatthew G. Knepley /* Return triangle subface for orientation o, if it is r for o == 0 */
334518a8359SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) {
3354bae88c7SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%3;
33642525629SMatthew G. Knepley }
337de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) {
338de65f515SMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 3+s-o)%3;
339de65f515SMatthew G. Knepley }
34042525629SMatthew G. Knepley 
341e5337592SStefano Zampini /* Return the interior edge number connecting the midpoints of the triangle edges r
342e5337592SStefano Zampini    and r+1 in the transitive closure for triangle orientation o */
343e5337592SStefano Zampini PETSC_STATIC_INLINE PetscInt GetTriMidEdge_Static(PetscInt o, PetscInt r) {
344431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+r) : o+r)%3;
345431647a4SMatthew G. Knepley }
346e5337592SStefano Zampini PETSC_STATIC_INLINE PetscInt GetTriMidEdgeInverse_Static(PetscInt o, PetscInt s) {
347431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+s) : 3+s-o)%3;
348431647a4SMatthew G. Knepley }
349431647a4SMatthew G. Knepley 
350e5337592SStefano Zampini /* Return the interior edge number connecting the midpoint of the triangle edge r
351e5337592SStefano Zampini    (in the transitive closure) and the vertex in the interior of the face for triangle orientation o */
352e5337592SStefano Zampini PETSC_STATIC_INLINE PetscInt GetTriInteriorEdge_Static(PetscInt o, PetscInt r) {
353e5337592SStefano Zampini   return (o < 0 ? 2-(o+r) : o+r)%3;
354e5337592SStefano Zampini }
355e5337592SStefano Zampini PETSC_STATIC_INLINE PetscInt GetTriInteriorEdgeInverse_Static(PetscInt o, PetscInt s) {
356e5337592SStefano Zampini   return (o < 0 ? 2-(o+s) : 3+s-o)%3;
357e5337592SStefano Zampini }
35842525629SMatthew G. Knepley 
359e3f8b1d6SMatthew G. Knepley /* Return quad edge for orientation o, if it is r for o == 0 */
360e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) {
361e3f8b1d6SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%4;
362e3f8b1d6SMatthew G. Knepley }
363d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) {
364d6d937efSMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 4+s-o)%4;
365d6d937efSMatthew G. Knepley }
366e3f8b1d6SMatthew G. Knepley 
367e3f8b1d6SMatthew G. Knepley /* Return quad subface for orientation o, if it is r for o == 0 */
368e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) {
3694bae88c7SMatthew G. Knepley   return (o < 0 ? 4-(o+r) : o+r)%4;
37042525629SMatthew G. Knepley }
371d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) {
372d6d937efSMatthew G. Knepley   return (o < 0 ? 4-(o+s) : 4+s-o)%4;
373d6d937efSMatthew G. Knepley }
37442525629SMatthew G. Knepley 
3756d7373e8SToby Isaac static PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt cStart, PetscInt cEnd)
3766d7373e8SToby Isaac {
3776d7373e8SToby Isaac   IS             cIS;
3786d7373e8SToby Isaac   PetscErrorCode ierr;
3796d7373e8SToby Isaac 
3806d7373e8SToby Isaac   PetscFunctionBegin;
3816d7373e8SToby Isaac   ierr = ISCreateStride(PETSC_COMM_SELF, cEnd - cStart, cStart, 1, &cIS);CHKERRQ(ierr);
3826d7373e8SToby Isaac   ierr = DMLabelSetStratumIS(label, value, cIS);CHKERRQ(ierr);
3836d7373e8SToby Isaac   ierr = ISDestroy(&cIS);CHKERRQ(ierr);
3846d7373e8SToby Isaac   PetscFunctionReturn(0);
3856d7373e8SToby Isaac }
3866d7373e8SToby Isaac 
38786150812SJed Brown static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
38875d3a19aSMatthew G. Knepley {
3896d7373e8SToby Isaac   PetscInt       depth, cStart, cStartNew, cEnd, cEndNew, cMax, c, vStart, vStartNew, vEnd, vEndNew, vMax, v, fStart, fStartNew, fEnd, fEndNew, fMax, f, eStart, eStartNew, eEnd, eEndNew, eMax, e, r;
3906d7373e8SToby Isaac   DMLabel        depthLabel;
39175d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
39275d3a19aSMatthew G. Knepley 
39375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
3942a5d0125SJed Brown   if (!refiner) PetscFunctionReturn(0);
39575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
39675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
39775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
39875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
39975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
40075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
4012a5d0125SJed Brown   ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
4026d7373e8SToby Isaac   ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr);
4036d7373e8SToby Isaac   ierr = DMCreateLabel(rdm,"depth");CHKERRQ(ierr);
4046d7373e8SToby Isaac   ierr = DMPlexGetDepthLabel(rdm,&depthLabel);CHKERRQ(ierr);
405*d918548eSToby Isaac   ierr = DMLabelSetStratumBounds(depthLabel, 0, vStartNew, vEndNew);CHKERRQ(ierr);
4066d7373e8SToby Isaac   if (depth > 2) ierr = DMLabelSetStratumBounds(depthLabel, 1, eStartNew, eEndNew);CHKERRQ(ierr);
407*d918548eSToby Isaac   if (depth > 1) ierr = DMLabelSetStratumBounds(depthLabel, depth - 1, fStartNew, fEndNew);CHKERRQ(ierr);
408*d918548eSToby Isaac   if (depth > 0) ierr = DMLabelSetStratumBounds(depthLabel, depth, cStartNew, cEndNew);CHKERRQ(ierr);
4096d7373e8SToby Isaac   {
4106d7373e8SToby Isaac     DM_Plex *plex = (DM_Plex *) rdm->data;
4116d7373e8SToby Isaac     ierr = DMLabelGetState(depthLabel, &plex->depthState);CHKERRQ(ierr);
4126d7373e8SToby Isaac   }
41375d3a19aSMatthew G. Knepley   switch (refiner) {
4140314a74cSLawrence Mitchell   case REFINER_SIMPLEX_1D:
4150314a74cSLawrence Mitchell     /* All cells have 2 vertices */
4160314a74cSLawrence Mitchell     for (c = cStart; c < cEnd; ++c) {
4170314a74cSLawrence Mitchell       for (r = 0; r < 2; ++r) {
4180314a74cSLawrence Mitchell         const PetscInt newp = cStartNew + (c - cStart)*2 + r;
4190314a74cSLawrence Mitchell 
4200314a74cSLawrence Mitchell         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
4210314a74cSLawrence Mitchell       }
4220314a74cSLawrence Mitchell     }
4230314a74cSLawrence Mitchell     /* Old vertices have identical supports */
4240314a74cSLawrence Mitchell     for (v = vStart; v < vEnd; ++v) {
4250314a74cSLawrence Mitchell       const PetscInt newp = vStartNew + (v - vStart);
4260314a74cSLawrence Mitchell       PetscInt       size;
4270314a74cSLawrence Mitchell 
4280314a74cSLawrence Mitchell       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
4290314a74cSLawrence Mitchell       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
4300314a74cSLawrence Mitchell     }
4310314a74cSLawrence Mitchell     /* Cell vertices have support 2 */
4320314a74cSLawrence Mitchell     for (c = cStart; c < cEnd; ++c) {
4330314a74cSLawrence Mitchell       const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart);
4340314a74cSLawrence Mitchell 
4350314a74cSLawrence Mitchell       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
4360314a74cSLawrence Mitchell     }
4370314a74cSLawrence Mitchell     break;
4389b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
43975d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
44075d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
44175d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
44275d3a19aSMatthew G. Knepley         const PetscInt newp = (c - cStart)*4 + r;
44375d3a19aSMatthew G. Knepley 
44475d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
44575d3a19aSMatthew G. Knepley       }
44675d3a19aSMatthew G. Knepley     }
44775d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
44875d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
44975d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
45075d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
45175d3a19aSMatthew G. Knepley         PetscInt       size;
45275d3a19aSMatthew G. Knepley 
45375d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
45475d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
45575d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
45675d3a19aSMatthew G. Knepley       }
45775d3a19aSMatthew G. Knepley     }
45875d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
45975d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
46075d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
46175d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
46275d3a19aSMatthew G. Knepley 
46375d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
46475d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
46575d3a19aSMatthew G. Knepley       }
46675d3a19aSMatthew G. Knepley     }
46775d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
46875d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
46975d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
47075d3a19aSMatthew G. Knepley       PetscInt       size;
47175d3a19aSMatthew G. Knepley 
47275d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
47375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
47475d3a19aSMatthew G. Knepley     }
47575d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
47675d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
47775d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
47875d3a19aSMatthew G. Knepley       PetscInt       size;
47975d3a19aSMatthew G. Knepley 
48075d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
48175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr);
48275d3a19aSMatthew G. Knepley     }
48375d3a19aSMatthew G. Knepley     break;
484e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_2D:
485e5337592SStefano Zampini     /* All cells have 4 faces */
486e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
487e5337592SStefano Zampini       for (r = 0; r < 3; ++r) {
488e5337592SStefano Zampini         const PetscInt newp = (c - cStart)*3 + r;
489e5337592SStefano Zampini 
490e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
491e5337592SStefano Zampini       }
492e5337592SStefano Zampini     }
493e5337592SStefano Zampini     /* Split faces have 2 vertices and the same cells as the parent */
494e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
495e5337592SStefano Zampini       for (r = 0; r < 2; ++r) {
496e5337592SStefano Zampini         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
497e5337592SStefano Zampini         PetscInt       size;
498e5337592SStefano Zampini 
499e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
500e5337592SStefano Zampini         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
501e5337592SStefano Zampini         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
502e5337592SStefano Zampini       }
503e5337592SStefano Zampini     }
504e5337592SStefano Zampini     /* Interior faces have 2 vertices and 2 cells */
505e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
506e5337592SStefano Zampini       for (r = 0; r < 3; ++r) {
507e5337592SStefano Zampini         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
508e5337592SStefano Zampini 
509e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
510e5337592SStefano Zampini         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
511e5337592SStefano Zampini       }
512e5337592SStefano Zampini     }
513e5337592SStefano Zampini     /* Old vertices have identical supports */
514e5337592SStefano Zampini     for (v = vStart; v < vEnd; ++v) {
515e5337592SStefano Zampini       const PetscInt newp = vStartNew + (v - vStart);
516e5337592SStefano Zampini       PetscInt       size;
517e5337592SStefano Zampini 
518e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
519e5337592SStefano Zampini       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
520e5337592SStefano Zampini     }
521e5337592SStefano Zampini     /* Split-face vertices have cells + 2 supports */
522e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
523e5337592SStefano Zampini       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
524e5337592SStefano Zampini       PetscInt       size;
525e5337592SStefano Zampini 
526e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
527e5337592SStefano Zampini       ierr = DMPlexSetSupportSize(rdm, newp, size + 2);CHKERRQ(ierr);
528e5337592SStefano Zampini     }
529e5337592SStefano Zampini     /* Interior vertices have 3 supports */
530e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
531e5337592SStefano Zampini       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
532e5337592SStefano Zampini 
533e5337592SStefano Zampini       ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr);
534e5337592SStefano Zampini     }
535e5337592SStefano Zampini     break;
5369b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
53775d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
53875d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
53975d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
540149f48fdSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
54175d3a19aSMatthew G. Knepley 
54275d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
54375d3a19aSMatthew G. Knepley       }
54475d3a19aSMatthew G. Knepley     }
54575d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
54675d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
54775d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
54875d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
54975d3a19aSMatthew G. Knepley         PetscInt       size;
55075d3a19aSMatthew G. Knepley 
55175d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
55275d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
55375d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
55475d3a19aSMatthew G. Knepley       }
55575d3a19aSMatthew G. Knepley     }
55675d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
55775d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
55875d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
55975d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
56075d3a19aSMatthew G. Knepley 
56175d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
56275d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
56375d3a19aSMatthew G. Knepley       }
56475d3a19aSMatthew G. Knepley     }
56575d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
56675d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
56775d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
56875d3a19aSMatthew G. Knepley       PetscInt       size;
56975d3a19aSMatthew G. Knepley 
57075d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
57175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
57275d3a19aSMatthew G. Knepley     }
57375d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
57475d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
57575d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
57675d3a19aSMatthew G. Knepley       PetscInt       size;
57775d3a19aSMatthew G. Knepley 
57875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
57975d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
58075d3a19aSMatthew G. Knepley     }
58175d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
58275d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
58375d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
58475d3a19aSMatthew G. Knepley 
58575d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
58675d3a19aSMatthew G. Knepley     }
58775d3a19aSMatthew G. Knepley     break;
5889b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
58975d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
59075d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
59175d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
59275d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
59375d3a19aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
59475d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
59575d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
59675d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
59775d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
59875d3a19aSMatthew G. Knepley 
59975d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
60075d3a19aSMatthew G. Knepley       }
60175d3a19aSMatthew G. Knepley     }
60275d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
60375d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
60475d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
60575d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
60675d3a19aSMatthew G. Knepley 
60775d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
60875d3a19aSMatthew G. Knepley       }
60975d3a19aSMatthew G. Knepley     }
61075d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
61175d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
61275d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
61375d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
61475d3a19aSMatthew G. Knepley         PetscInt       size;
61575d3a19aSMatthew G. Knepley 
61675d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
61775d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
61875d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
61975d3a19aSMatthew G. Knepley       }
62075d3a19aSMatthew G. Knepley     }
62175d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
62275d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
62375d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
62475d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
62575d3a19aSMatthew G. Knepley 
62675d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
62775d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
62875d3a19aSMatthew G. Knepley       }
62975d3a19aSMatthew G. Knepley     }
63075d3a19aSMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
63175d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
63275d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
63375d3a19aSMatthew G. Knepley       PetscInt       size;
63475d3a19aSMatthew G. Knepley 
63575d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
63675d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
63775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
63875d3a19aSMatthew G. Knepley     }
63975d3a19aSMatthew G. Knepley     /* Hybrid cell faces have 2 vertices and 2 cells */
64075d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
64175d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
64275d3a19aSMatthew G. Knepley 
64375d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
64475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
64575d3a19aSMatthew G. Knepley     }
64675d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
64775d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
64875d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
64975d3a19aSMatthew G. Knepley       PetscInt       size;
65075d3a19aSMatthew G. Knepley 
65175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
65275d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
65375d3a19aSMatthew G. Knepley     }
65475d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
65575d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
65675d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
65775d3a19aSMatthew G. Knepley       const PetscInt *support;
65875d3a19aSMatthew G. Knepley       PetscInt       size, newSize = 2, s;
65975d3a19aSMatthew G. Knepley 
66075d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
66175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
66275d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
66375d3a19aSMatthew G. Knepley         if (support[s] >= cMax) newSize += 1;
66475d3a19aSMatthew G. Knepley         else newSize += 2;
66575d3a19aSMatthew G. Knepley       }
66675d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr);
66775d3a19aSMatthew G. Knepley     }
66875d3a19aSMatthew G. Knepley     break;
6699b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
670a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
671a97b51b8SMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
672a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
673a97b51b8SMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
674a97b51b8SMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
675a97b51b8SMatthew G. Knepley     /* Interior cells have 4 faces */
676a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
677a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
678a97b51b8SMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
679a97b51b8SMatthew G. Knepley 
680a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
681a97b51b8SMatthew G. Knepley       }
682a97b51b8SMatthew G. Knepley     }
683a97b51b8SMatthew G. Knepley     /* Hybrid cells have 4 faces */
684a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
685a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
686a97b51b8SMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
687a97b51b8SMatthew G. Knepley 
688a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
689a97b51b8SMatthew G. Knepley       }
690a97b51b8SMatthew G. Knepley     }
691a97b51b8SMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
692a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
693a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
694a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
695a97b51b8SMatthew G. Knepley         PetscInt       size;
696a97b51b8SMatthew G. Knepley 
697a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
698a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
699a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
700a97b51b8SMatthew G. Knepley       }
701a97b51b8SMatthew G. Knepley     }
702a97b51b8SMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
703a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
704a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
705a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
706a97b51b8SMatthew G. Knepley 
707a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
708a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
709a97b51b8SMatthew G. Knepley       }
710a97b51b8SMatthew G. Knepley     }
711a97b51b8SMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
712a97b51b8SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
713a97b51b8SMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
714a97b51b8SMatthew G. Knepley       PetscInt       size;
715a97b51b8SMatthew G. Knepley 
716a97b51b8SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
717a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
718a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
719a97b51b8SMatthew G. Knepley     }
720a97b51b8SMatthew G. Knepley     /* Hybrid cell faces have 2 vertices and 2 cells */
721a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
722a97b51b8SMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
723a97b51b8SMatthew G. Knepley 
724a97b51b8SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
725a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
726a97b51b8SMatthew G. Knepley     }
727a97b51b8SMatthew G. Knepley     /* Old vertices have identical supports */
728a97b51b8SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
729a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
730a97b51b8SMatthew G. Knepley       PetscInt       size;
731a97b51b8SMatthew G. Knepley 
732a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
733a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
734a97b51b8SMatthew G. Knepley     }
735a97b51b8SMatthew G. Knepley     /* Face vertices have 2 + cells supports */
736a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
737a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
738a97b51b8SMatthew G. Knepley       PetscInt       size;
739a97b51b8SMatthew G. Knepley 
740a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
741a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
742a97b51b8SMatthew G. Knepley     }
743a97b51b8SMatthew G. Knepley     /* Cell vertices have 4 supports */
744a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
745a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
746a97b51b8SMatthew G. Knepley 
747a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
748a97b51b8SMatthew G. Knepley     }
749a97b51b8SMatthew G. Knepley     break;
7509b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
751b5da9499SMatthew G. Knepley     /* All cells have 4 faces */
752b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
753b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
754dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
755b5da9499SMatthew G. Knepley 
756b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
757b5da9499SMatthew G. Knepley       }
758b5da9499SMatthew G. Knepley     }
759b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
760b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
761b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
762b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
763b5da9499SMatthew G. Knepley         PetscInt       size;
764b5da9499SMatthew G. Knepley 
765b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
766b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
767b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
768b5da9499SMatthew G. Knepley       }
769b5da9499SMatthew G. Knepley     }
7709ddff745SMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
771b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
772b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
773b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r;
774b5da9499SMatthew G. Knepley 
775b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
776b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
777b5da9499SMatthew G. Knepley       }
778b5da9499SMatthew G. Knepley     }
779b5da9499SMatthew G. Knepley     /* Split edges have 2 vertices and the same faces */
780b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
781b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
782b5da9499SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
783b5da9499SMatthew G. Knepley         PetscInt       size;
784b5da9499SMatthew G. Knepley 
785b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
786b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
787b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
788b5da9499SMatthew G. Knepley       }
789b5da9499SMatthew G. Knepley     }
790b5da9499SMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
791b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
792b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
793b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
794b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
795b5da9499SMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
796b5da9499SMatthew G. Knepley 
797b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
798b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
799b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
800b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
801b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
802b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
803b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
804b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
80586f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
806e5337592SStefano Zampini           er = GetTriMidEdgeInverse_Static(ornt[c], r);
807b5da9499SMatthew G. Knepley           if (er == eint[c]) {
808b5da9499SMatthew G. Knepley             intFaces += 1;
809b5da9499SMatthew G. Knepley           } else {
810b5da9499SMatthew G. Knepley             intFaces += 2;
811b5da9499SMatthew G. Knepley           }
812b5da9499SMatthew G. Knepley         }
813b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
814b5da9499SMatthew G. Knepley       }
815b5da9499SMatthew G. Knepley     }
8169ddff745SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
817b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
818b5da9499SMatthew G. Knepley       const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
819b5da9499SMatthew G. Knepley 
820b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
821b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
822b5da9499SMatthew G. Knepley     }
823b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
824b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
825b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
826b5da9499SMatthew G. Knepley       PetscInt       size;
827b5da9499SMatthew G. Knepley 
828b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
829b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
830b5da9499SMatthew G. Knepley     }
831b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + faces*2 + cells*0/1 supports */
832b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
833b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
834b5da9499SMatthew G. Knepley       PetscInt       size, *star = NULL, starSize, s, cellSize = 0;
835b5da9499SMatthew G. Knepley 
836b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
837b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
838b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
839b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
840b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
841b5da9499SMatthew G. Knepley 
842b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
843b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
844b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
845b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
846b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
84742525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
848b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
849b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
850b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
85142525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
85242525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
853b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
854b5da9499SMatthew G. Knepley         }
855b5da9499SMatthew G. Knepley       }
856b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
857b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr);
858b5da9499SMatthew G. Knepley     }
859b5da9499SMatthew G. Knepley     break;
8609b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
8616ce3c06aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart),
8626ce3c06aSMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
863dae4404aSMatthew G. Knepley     /* Interior cells have 4 faces */
864dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
865dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
866dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
867dae4404aSMatthew G. Knepley 
868dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
869dae4404aSMatthew G. Knepley       }
870dae4404aSMatthew G. Knepley     }
871dae4404aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
872dae4404aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
873dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
874dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
875dae4404aSMatthew G. Knepley 
876dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr);
877dae4404aSMatthew G. Knepley       }
878dae4404aSMatthew G. Knepley     }
8796ce3c06aSMatthew G. Knepley     /* Interior split faces have 3 edges and the same cells as the parent */
880dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
881dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
882dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
883dae4404aSMatthew G. Knepley         PetscInt       size;
884dae4404aSMatthew G. Knepley 
885dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
886dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
887dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
888dae4404aSMatthew G. Knepley       }
889dae4404aSMatthew G. Knepley     }
890dae4404aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
891dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
892dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
893dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r;
894dae4404aSMatthew G. Knepley 
895dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
896dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
897dae4404aSMatthew G. Knepley       }
898dae4404aSMatthew G. Knepley     }
8996ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
9006ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
9016ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
9026ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
9036ce3c06aSMatthew G. Knepley         PetscInt       size;
9046ce3c06aSMatthew G. Knepley 
9056ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
9066ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
9076ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
9086ce3c06aSMatthew G. Knepley       }
9096ce3c06aSMatthew G. Knepley     }
9106ce3c06aSMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
9116ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
9126ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
9136ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r;
9146ce3c06aSMatthew G. Knepley 
9156ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
9166ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
9176ce3c06aSMatthew G. Knepley       }
9186ce3c06aSMatthew G. Knepley     }
9196ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces */
920dae4404aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
921dae4404aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
922dae4404aSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
923dae4404aSMatthew G. Knepley         PetscInt       size;
924dae4404aSMatthew G. Knepley 
925dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
926dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
927dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
928dae4404aSMatthew G. Knepley       }
929dae4404aSMatthew G. Knepley     }
9306ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
931dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
932dae4404aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
933dae4404aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
934dae4404aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
935dae4404aSMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
936dae4404aSMatthew G. Knepley 
937dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
938dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
939dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
940dae4404aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
941dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
942dae4404aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
943dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
944dae4404aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
9456ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
946dae4404aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
947e5337592SStefano Zampini             er = GetTriMidEdgeInverse_Static(ornt[c], r);
948dae4404aSMatthew G. Knepley             if (er == eint[c]) {
949dae4404aSMatthew G. Knepley               intFaces += 1;
950dae4404aSMatthew G. Knepley             } else {
951dae4404aSMatthew G. Knepley               intFaces += 2;
952dae4404aSMatthew G. Knepley             }
9536ce3c06aSMatthew G. Knepley           } else {
9546ce3c06aSMatthew G. Knepley             intFaces += 1;
9556ce3c06aSMatthew G. Knepley           }
956dae4404aSMatthew G. Knepley         }
957dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
958dae4404aSMatthew G. Knepley       }
959dae4404aSMatthew G. Knepley     }
9606ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
961dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
962dae4404aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
963dae4404aSMatthew G. Knepley 
964dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
965dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
966dae4404aSMatthew G. Knepley     }
9676ce3c06aSMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
968dae4404aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
9696ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
9706ce3c06aSMatthew G. Knepley       PetscInt       size;
9716ce3c06aSMatthew G. Knepley 
9726ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
9736ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
9746ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
9756ce3c06aSMatthew G. Knepley     }
9766ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
9776ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
9786ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
979dae4404aSMatthew G. Knepley       PetscInt       size;
980dae4404aSMatthew G. Knepley 
981dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
982dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
9836ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr);
984dae4404aSMatthew G. Knepley     }
9856ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
986dae4404aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
987dae4404aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
988dae4404aSMatthew G. Knepley       PetscInt       size;
989dae4404aSMatthew G. Knepley 
990dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
991dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
992dae4404aSMatthew G. Knepley     }
9936ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
9946ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
9956ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
996dae4404aSMatthew G. Knepley       const PetscInt *support;
9976ce3c06aSMatthew G. Knepley       PetscInt        size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0;
998dae4404aSMatthew G. Knepley 
9996ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
10006ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
1001dae4404aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
10026ce3c06aSMatthew G. Knepley         if (support[s] < fMax) faceSize += 2;
10036ce3c06aSMatthew G. Knepley         else                   faceSize += 1;
1004dae4404aSMatthew G. Knepley       }
10056ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
10066ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
10076ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
10086ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
10096ce3c06aSMatthew G. Knepley 
10106ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
10116ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
10126ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
10136ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
10146ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
10156ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
10166ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
10176ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
10186ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
10196ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
10206ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
10216ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
10226ce3c06aSMatthew G. Knepley         }
10236ce3c06aSMatthew G. Knepley       }
10246ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
10256ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr);
1026dae4404aSMatthew G. Knepley     }
1027dae4404aSMatthew G. Knepley     break;
1028e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_3D:
1029e5337592SStefano Zampini     /* All cells have 6 faces */
1030e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
1031e5337592SStefano Zampini       for (r = 0; r < 4; ++r) {
1032e5337592SStefano Zampini         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
1033e5337592SStefano Zampini 
1034e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
1035e5337592SStefano Zampini       }
1036e5337592SStefano Zampini     }
1037e5337592SStefano Zampini     /* Split faces have 4 edges and the same cells as the parent */
1038e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
1039e5337592SStefano Zampini       for (r = 0; r < 3; ++r) {
1040e5337592SStefano Zampini         const PetscInt newp = fStartNew + (f - fStart)*3 + r;
1041e5337592SStefano Zampini         PetscInt       size;
1042e5337592SStefano Zampini 
1043e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
1044e5337592SStefano Zampini         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
1045e5337592SStefano Zampini         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
1046e5337592SStefano Zampini       }
1047e5337592SStefano Zampini     }
1048e5337592SStefano Zampini     /* Interior cell faces have 4 edges and 2 cells */
1049e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
1050e5337592SStefano Zampini       for (r = 0; r < 6; ++r) {
1051e5337592SStefano Zampini         const PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + r;
1052e5337592SStefano Zampini 
1053e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
1054e5337592SStefano Zampini         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
1055e5337592SStefano Zampini       }
1056e5337592SStefano Zampini     }
1057e5337592SStefano Zampini     /* Split edges have 2 vertices and the same faces */
1058e5337592SStefano Zampini     for (e = eStart; e < eEnd; ++e) {
1059e5337592SStefano Zampini       for (r = 0; r < 2; ++r) {
1060e5337592SStefano Zampini         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
1061e5337592SStefano Zampini         PetscInt       size;
1062e5337592SStefano Zampini 
1063e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
1064e5337592SStefano Zampini         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
1065e5337592SStefano Zampini         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
1066e5337592SStefano Zampini       }
1067e5337592SStefano Zampini     }
1068e5337592SStefano Zampini     /* Face edges have 2 vertices and 2 + cell faces supports */
1069e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
1070e5337592SStefano Zampini       for (r = 0; r < 3; ++r) {
1071e5337592SStefano Zampini         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
1072e5337592SStefano Zampini         PetscInt        size;
1073e5337592SStefano Zampini 
1074e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
1075e5337592SStefano Zampini         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
1076e5337592SStefano Zampini         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
1077e5337592SStefano Zampini       }
1078e5337592SStefano Zampini     }
1079e5337592SStefano Zampini     /* Interior cell edges have 2 vertices and 3 faces */
1080e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
1081e5337592SStefano Zampini       for (r = 0; r < 4; ++r) {
1082e5337592SStefano Zampini         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r;
1083e5337592SStefano Zampini 
1084e5337592SStefano Zampini         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
1085e5337592SStefano Zampini         ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr);
1086e5337592SStefano Zampini       }
1087e5337592SStefano Zampini     }
1088e5337592SStefano Zampini     /* Old vertices have identical supports */
1089e5337592SStefano Zampini     for (v = vStart; v < vEnd; ++v) {
1090e5337592SStefano Zampini       const PetscInt newp = vStartNew + (v - vStart);
1091e5337592SStefano Zampini       PetscInt       size;
1092e5337592SStefano Zampini 
1093e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
1094e5337592SStefano Zampini       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
1095e5337592SStefano Zampini     }
1096e5337592SStefano Zampini     /* Edge vertices have 2 + faces supports */
1097e5337592SStefano Zampini     for (e = eStart; e < eEnd; ++e) {
1098e5337592SStefano Zampini       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
1099e5337592SStefano Zampini       PetscInt       size;
1100e5337592SStefano Zampini 
1101e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
1102e5337592SStefano Zampini       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
1103e5337592SStefano Zampini     }
1104e5337592SStefano Zampini     /* Face vertices have 3 + cells supports */
1105e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
1106e5337592SStefano Zampini       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart;
1107e5337592SStefano Zampini       PetscInt       size;
1108e5337592SStefano Zampini 
1109e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
1110e5337592SStefano Zampini       ierr = DMPlexSetSupportSize(rdm, newp, 3 + size);CHKERRQ(ierr);
1111e5337592SStefano Zampini     }
1112e5337592SStefano Zampini     /* Interior cell vertices have 4 supports */
1113e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
1114e5337592SStefano Zampini       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + fEnd - fStart + c - cStart;
1115e5337592SStefano Zampini 
1116e5337592SStefano Zampini       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
1117e5337592SStefano Zampini     }
1118e5337592SStefano Zampini     break;
11199b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
11202eabf88fSMatthew G. Knepley     /* All cells have 6 faces */
11212eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
11222eabf88fSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
11232eabf88fSMatthew G. Knepley         const PetscInt newp = (c - cStart)*8 + r;
11242eabf88fSMatthew G. Knepley 
11252eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
11262eabf88fSMatthew G. Knepley       }
11272eabf88fSMatthew G. Knepley     }
11282eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
11292eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
11302eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
11312eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
11322eabf88fSMatthew G. Knepley         PetscInt       size;
11332eabf88fSMatthew G. Knepley 
11342eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
11352eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
11362eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
11372eabf88fSMatthew G. Knepley       }
11382eabf88fSMatthew G. Knepley     }
11392eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
11402eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
11412eabf88fSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
11422eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
11432eabf88fSMatthew G. Knepley 
11442eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
11452eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
11462eabf88fSMatthew G. Knepley       }
11472eabf88fSMatthew G. Knepley     }
11482eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
11492eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
11502eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
11512eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
11522eabf88fSMatthew G. Knepley         PetscInt       size;
11532eabf88fSMatthew G. Knepley 
11542eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
11552eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
11562eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
11572eabf88fSMatthew G. Knepley       }
11582eabf88fSMatthew G. Knepley     }
11592eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
11602eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
11612eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
11622eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
11632eabf88fSMatthew G. Knepley         PetscInt       size;
11642eabf88fSMatthew G. Knepley 
11652eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
11662eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
11672eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
11682eabf88fSMatthew G. Knepley       }
11692eabf88fSMatthew G. Knepley     }
11702eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
11712eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
11722eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
11732eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
11742eabf88fSMatthew G. Knepley 
11752eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
11762eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
11772eabf88fSMatthew G. Knepley       }
11782eabf88fSMatthew G. Knepley     }
11792eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
11802eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
11812eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
11822eabf88fSMatthew G. Knepley       PetscInt       size;
11832eabf88fSMatthew G. Knepley 
11842eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
11852eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
11862eabf88fSMatthew G. Knepley     }
11872eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
11882eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
11892eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
11902eabf88fSMatthew G. Knepley       PetscInt       size;
11912eabf88fSMatthew G. Knepley 
11922eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
11932eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
11942eabf88fSMatthew G. Knepley     }
11952eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
11962eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
11972eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
11982eabf88fSMatthew G. Knepley       PetscInt       size;
11992eabf88fSMatthew G. Knepley 
12002eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
12012eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
12022eabf88fSMatthew G. Knepley     }
12032eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
12042eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
12052eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
12062eabf88fSMatthew G. Knepley 
12072eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
12082eabf88fSMatthew G. Knepley     }
12092eabf88fSMatthew G. Knepley     break;
12109b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
121127fcede3SMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart),
121227fcede3SMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
121327fcede3SMatthew G. Knepley     /* Interior cells have 6 faces */
121427fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
121527fcede3SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
121627fcede3SMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
121727fcede3SMatthew G. Knepley 
121827fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
121927fcede3SMatthew G. Knepley       }
122027fcede3SMatthew G. Knepley     }
122127fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces */
122227fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
122327fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
122427fcede3SMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
122527fcede3SMatthew G. Knepley 
122627fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
122727fcede3SMatthew G. Knepley       }
122827fcede3SMatthew G. Knepley     }
122927fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
123027fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
123127fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
123227fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
123327fcede3SMatthew G. Knepley         PetscInt       size;
123427fcede3SMatthew G. Knepley 
123527fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
123627fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
123727fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
123827fcede3SMatthew G. Knepley       }
123927fcede3SMatthew G. Knepley     }
124027fcede3SMatthew G. Knepley     /* Interior cell faces have 4 edges and 2 cells */
124127fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
124227fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
124327fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
124427fcede3SMatthew G. Knepley 
124527fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
124627fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
124727fcede3SMatthew G. Knepley       }
124827fcede3SMatthew G. Knepley     }
124927fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
125027fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
125127fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
125227fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
125327fcede3SMatthew G. Knepley         PetscInt       size;
125427fcede3SMatthew G. Knepley 
125527fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
125627fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
125727fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
125827fcede3SMatthew G. Knepley       }
125927fcede3SMatthew G. Knepley     }
126027fcede3SMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
126127fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
126227fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
126327fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r;
126427fcede3SMatthew G. Knepley 
126527fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
126627fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
126727fcede3SMatthew G. Knepley       }
126827fcede3SMatthew G. Knepley     }
126927fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
127027fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
127127fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
127227fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
127327fcede3SMatthew G. Knepley         PetscInt       size;
127427fcede3SMatthew G. Knepley 
127527fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
127627fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
127727fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
127827fcede3SMatthew G. Knepley       }
127927fcede3SMatthew G. Knepley     }
128027fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
128127fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
128227fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
128327fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
128427fcede3SMatthew G. Knepley         PetscInt       size;
128527fcede3SMatthew G. Knepley 
128627fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
128727fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
128827fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
128927fcede3SMatthew G. Knepley       }
129027fcede3SMatthew G. Knepley     }
129127fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
129227fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
129327fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
129427fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
129527fcede3SMatthew G. Knepley 
129627fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
129727fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
129827fcede3SMatthew G. Knepley       }
129927fcede3SMatthew G. Knepley     }
130027fcede3SMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
130127fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
130227fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
130327fcede3SMatthew G. Knepley       PetscInt       size;
130427fcede3SMatthew G. Knepley 
130527fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
130627fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
130727fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
130827fcede3SMatthew G. Knepley     }
130927fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
131027fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
131127fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
131227fcede3SMatthew G. Knepley       PetscInt       size;
131327fcede3SMatthew G. Knepley 
131427fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
131527fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
131627fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
131727fcede3SMatthew G. Knepley     }
131827fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
131927fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
132027fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
132127fcede3SMatthew G. Knepley 
132227fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
132327fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
132427fcede3SMatthew G. Knepley     }
132527fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
132627fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
132727fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
132827fcede3SMatthew G. Knepley       PetscInt       size;
132927fcede3SMatthew G. Knepley 
133027fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
133127fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
133227fcede3SMatthew G. Knepley     }
133327fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
133427fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
133527fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
133627fcede3SMatthew G. Knepley       PetscInt       size;
133727fcede3SMatthew G. Knepley 
133827fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
133927fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
134027fcede3SMatthew G. Knepley     }
134127fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
134227fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
134327fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
134427fcede3SMatthew G. Knepley       PetscInt       size;
134527fcede3SMatthew G. Knepley 
134627fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
134727fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
134827fcede3SMatthew G. Knepley     }
134927fcede3SMatthew G. Knepley     /* Interior cell vertices have 6 supports */
135027fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
135127fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
135227fcede3SMatthew G. Knepley 
135327fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
135427fcede3SMatthew G. Knepley     }
135527fcede3SMatthew G. Knepley     break;
135675d3a19aSMatthew G. Knepley   default:
135775d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
135875d3a19aSMatthew G. Knepley   }
135975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
136075d3a19aSMatthew G. Knepley }
136175d3a19aSMatthew G. Knepley 
136286150812SJed Brown static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
136375d3a19aSMatthew G. Knepley {
1364b5da9499SMatthew G. Knepley   const PetscInt *faces, cellInd[4] = {0, 1, 2, 3};
13656ce3c06aSMatthew G. Knepley   PetscInt        cStart,    cEnd,    cMax,    vStart,    vEnd, vMax, fStart,    fEnd,    fMax,    eStart,    eEnd,    eMax;
13666ce3c06aSMatthew G. Knepley   PetscInt        cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew,    fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew;
13676ce3c06aSMatthew G. Knepley   PetscInt        depth, maxSupportSize, *supportRef, c, f, e, v, r, p;
136875d3a19aSMatthew G. Knepley   PetscErrorCode  ierr;
136975d3a19aSMatthew G. Knepley 
137075d3a19aSMatthew G. Knepley   PetscFunctionBegin;
13712a5d0125SJed Brown   if (!refiner) PetscFunctionReturn(0);
137275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
137375d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
137475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
137575d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
137675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
137775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
137875d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
137975d3a19aSMatthew G. Knepley   ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr);
138075d3a19aSMatthew G. Knepley   switch (refiner) {
13810314a74cSLawrence Mitchell   case REFINER_SIMPLEX_1D:
13820314a74cSLawrence Mitchell     /* Max support size of refined mesh is 2 */
13830314a74cSLawrence Mitchell     ierr = PetscMalloc1(2, &supportRef);CHKERRQ(ierr);
13840314a74cSLawrence Mitchell     /* All cells have 2 vertices */
13850314a74cSLawrence Mitchell     for (c = cStart; c < cEnd; ++c) {
13860314a74cSLawrence Mitchell       const PetscInt  newv = vStartNew + (vEnd - vStart) + (c - cStart);
13870314a74cSLawrence Mitchell 
13880314a74cSLawrence Mitchell       for (r = 0; r < 2; ++r) {
13890314a74cSLawrence Mitchell         const PetscInt newp = cStartNew + (c - cStart)*2 + r;
13900314a74cSLawrence Mitchell         const PetscInt *cone;
13910314a74cSLawrence Mitchell         PetscInt        coneNew[2];
13920314a74cSLawrence Mitchell 
13930314a74cSLawrence Mitchell         ierr             = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
13940314a74cSLawrence Mitchell         coneNew[0]       = vStartNew + (cone[0] - vStart);
13950314a74cSLawrence Mitchell         coneNew[1]       = vStartNew + (cone[1] - vStart);
13960314a74cSLawrence Mitchell         coneNew[(r+1)%2] = newv;
13970314a74cSLawrence Mitchell         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
13980314a74cSLawrence Mitchell #if 1
13990314a74cSLawrence Mitchell         if ((newp < cStartNew) || (newp >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp, cStartNew, cEndNew);
14000314a74cSLawrence Mitchell         for (p = 0; p < 2; ++p) {
14010314a74cSLawrence 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);
14020314a74cSLawrence Mitchell         }
14030314a74cSLawrence Mitchell #endif
14040314a74cSLawrence Mitchell       }
14050314a74cSLawrence Mitchell     }
14060314a74cSLawrence Mitchell     /* Old vertices have identical supports */
14070314a74cSLawrence Mitchell     for (v = vStart; v < vEnd; ++v) {
14080314a74cSLawrence Mitchell       const PetscInt  newp = vStartNew + (v - vStart);
14090314a74cSLawrence Mitchell       const PetscInt *support, *cone;
14100314a74cSLawrence Mitchell       PetscInt        size, s;
14110314a74cSLawrence Mitchell 
14120314a74cSLawrence Mitchell       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
14130314a74cSLawrence Mitchell       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
14140314a74cSLawrence Mitchell       for (s = 0; s < size; ++s) {
14150314a74cSLawrence Mitchell         PetscInt r = 0;
14160314a74cSLawrence Mitchell 
14170314a74cSLawrence Mitchell         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
14180314a74cSLawrence Mitchell         if (cone[1] == v) r = 1;
14190314a74cSLawrence Mitchell         supportRef[s] = cStartNew + (support[s] - cStart)*2 + r;
14200314a74cSLawrence Mitchell       }
14210314a74cSLawrence Mitchell       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
14220314a74cSLawrence Mitchell #if 1
14230314a74cSLawrence Mitchell       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
14240314a74cSLawrence Mitchell       for (p = 0; p < size; ++p) {
14250314a74cSLawrence 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);
14260314a74cSLawrence Mitchell       }
14270314a74cSLawrence Mitchell #endif
14280314a74cSLawrence Mitchell     }
14290314a74cSLawrence Mitchell     /* Cell vertices have support of 2 cells */
14300314a74cSLawrence Mitchell     for (c = cStart; c < cEnd; ++c) {
14310314a74cSLawrence Mitchell       const PetscInt  newp = vStartNew + (vEnd - vStart) + (c - cStart);
14320314a74cSLawrence Mitchell 
14330314a74cSLawrence Mitchell       supportRef[0] = cStartNew + (c - cStart)*2 + 0;
14340314a74cSLawrence Mitchell       supportRef[1] = cStartNew + (c - cStart)*2 + 1;
14350314a74cSLawrence Mitchell       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
14360314a74cSLawrence Mitchell #if 1
14370314a74cSLawrence Mitchell       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
14380314a74cSLawrence Mitchell       for (p = 0; p < 2; ++p) {
14390314a74cSLawrence 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);
14400314a74cSLawrence Mitchell       }
14410314a74cSLawrence Mitchell #endif
14420314a74cSLawrence Mitchell     }
14430314a74cSLawrence Mitchell     ierr = PetscFree(supportRef);CHKERRQ(ierr);
14440314a74cSLawrence Mitchell     break;
14459b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
144675d3a19aSMatthew G. Knepley     /*
144775d3a19aSMatthew G. Knepley      2
144875d3a19aSMatthew G. Knepley      |\
144975d3a19aSMatthew G. Knepley      | \
145075d3a19aSMatthew G. Knepley      |  \
145175d3a19aSMatthew G. Knepley      |   \
145275d3a19aSMatthew G. Knepley      | C  \
145375d3a19aSMatthew G. Knepley      |     \
145475d3a19aSMatthew G. Knepley      |      \
145575d3a19aSMatthew G. Knepley      2---1---1
145675d3a19aSMatthew G. Knepley      |\  D  / \
145775d3a19aSMatthew G. Knepley      | 2   0   \
145875d3a19aSMatthew G. Knepley      |A \ /  B  \
145975d3a19aSMatthew G. Knepley      0---0-------1
146075d3a19aSMatthew G. Knepley      */
146175d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
146275d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
146375d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
146475d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
146575d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
146675d3a19aSMatthew G. Knepley 
146775d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
146875d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
146975d3a19aSMatthew G. Knepley       /* A triangle */
147075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
147175d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
147275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
147375d3a19aSMatthew G. Knepley       orntNew[1] = -2;
147475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
147575d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
147675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
147775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
147875d3a19aSMatthew G. Knepley #if 1
147975d3a19aSMatthew 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);
148075d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
148175d3a19aSMatthew 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);
148275d3a19aSMatthew G. Knepley       }
148375d3a19aSMatthew G. Knepley #endif
148475d3a19aSMatthew G. Knepley       /* B triangle */
148575d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
148675d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
148775d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
148875d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
148975d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
149075d3a19aSMatthew G. Knepley       orntNew[2] = -2;
149175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
149275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
149375d3a19aSMatthew G. Knepley #if 1
149475d3a19aSMatthew 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);
149575d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
149675d3a19aSMatthew 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);
149775d3a19aSMatthew G. Knepley       }
149875d3a19aSMatthew G. Knepley #endif
149975d3a19aSMatthew G. Knepley       /* C triangle */
150075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
150175d3a19aSMatthew G. Knepley       orntNew[0] = -2;
150275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
150375d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
150475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
150575d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
150675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
150775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
150875d3a19aSMatthew G. Knepley #if 1
150975d3a19aSMatthew 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);
151075d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
151175d3a19aSMatthew 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);
151275d3a19aSMatthew G. Knepley       }
151375d3a19aSMatthew G. Knepley #endif
151475d3a19aSMatthew G. Knepley       /* D triangle */
151575d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
151675d3a19aSMatthew G. Knepley       orntNew[0] = 0;
151775d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
151875d3a19aSMatthew G. Knepley       orntNew[1] = 0;
151975d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
152075d3a19aSMatthew G. Knepley       orntNew[2] = 0;
152175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
152275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
152375d3a19aSMatthew G. Knepley #if 1
152475d3a19aSMatthew 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);
152575d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
152675d3a19aSMatthew 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);
152775d3a19aSMatthew G. Knepley       }
152875d3a19aSMatthew G. Knepley #endif
152975d3a19aSMatthew G. Knepley     }
153075d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
153175d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1532854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
153375d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
153475d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
153575d3a19aSMatthew G. Knepley 
153675d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
153775d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1538297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
153975d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
154075d3a19aSMatthew G. Knepley 
154175d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
154275d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
154375d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
154475d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
154575d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
154675d3a19aSMatthew G. Knepley #if 1
154775d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
154875d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
154975d3a19aSMatthew 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);
155075d3a19aSMatthew G. Knepley         }
155175d3a19aSMatthew G. Knepley #endif
155275d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
155375d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
155475d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
155575d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
155675d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1557297d2bf4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
155875d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
155975d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
156075d3a19aSMatthew G. Knepley           }
1561297d2bf4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
156275d3a19aSMatthew G. Knepley         }
156375d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
156475d3a19aSMatthew G. Knepley #if 1
156575d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
156675d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
156775d3a19aSMatthew 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);
156875d3a19aSMatthew G. Knepley         }
156975d3a19aSMatthew G. Knepley #endif
157075d3a19aSMatthew G. Knepley       }
157175d3a19aSMatthew G. Knepley     }
157275d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
157375d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
157475d3a19aSMatthew G. Knepley       const PetscInt *cone;
157575d3a19aSMatthew G. Knepley 
157675d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
157775d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
157875d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
157975d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
158075d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
158175d3a19aSMatthew G. Knepley 
158275d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
158375d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
158475d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
158575d3a19aSMatthew G. Knepley #if 1
158675d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
158775d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
158875d3a19aSMatthew 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);
158975d3a19aSMatthew G. Knepley         }
159075d3a19aSMatthew G. Knepley #endif
159175d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
159275d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
159375d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
159475d3a19aSMatthew G. Knepley #if 1
159575d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
159675d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
159775d3a19aSMatthew 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);
159875d3a19aSMatthew G. Knepley         }
159975d3a19aSMatthew G. Knepley #endif
160075d3a19aSMatthew G. Knepley       }
160175d3a19aSMatthew G. Knepley     }
160275d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
160375d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
160475d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
160575d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
160675d3a19aSMatthew G. Knepley       PetscInt        size, s;
160775d3a19aSMatthew G. Knepley 
160875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
160975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
161075d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
161175d3a19aSMatthew G. Knepley         PetscInt r = 0;
161275d3a19aSMatthew G. Knepley 
161375d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
161475d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
161575d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
161675d3a19aSMatthew G. Knepley       }
161775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
161875d3a19aSMatthew G. Knepley #if 1
161975d3a19aSMatthew 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);
162075d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
162175d3a19aSMatthew 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);
162275d3a19aSMatthew G. Knepley       }
162375d3a19aSMatthew G. Knepley #endif
162475d3a19aSMatthew G. Knepley     }
162575d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
162675d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
162775d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
162875d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
162975d3a19aSMatthew G. Knepley       PetscInt        size, s;
163075d3a19aSMatthew G. Knepley 
163175d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
163275d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
163375d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
163475d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
163575d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
163675d3a19aSMatthew G. Knepley         PetscInt r = 0;
163775d3a19aSMatthew G. Knepley 
163875d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
163975d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
164075d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
164175d3a19aSMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
164275d3a19aSMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
164375d3a19aSMatthew G. Knepley       }
164475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
164575d3a19aSMatthew G. Knepley #if 1
164675d3a19aSMatthew 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);
164775d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
164875d3a19aSMatthew 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);
164975d3a19aSMatthew G. Knepley       }
165075d3a19aSMatthew G. Knepley #endif
165175d3a19aSMatthew G. Knepley     }
165275d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
165375d3a19aSMatthew G. Knepley     break;
1654e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_2D:
1655e5337592SStefano Zampini     /*
1656e5337592SStefano Zampini      2
1657e5337592SStefano Zampini      |\
1658e5337592SStefano Zampini      | \
1659e5337592SStefano Zampini      |  \
1660e5337592SStefano Zampini      |   \
1661e5337592SStefano Zampini      | C  \
1662e5337592SStefano Zampini      |     \
1663e5337592SStefano Zampini      2      1
1664e5337592SStefano Zampini      |\    / \
1665e5337592SStefano Zampini      | 2  1   \
1666e5337592SStefano Zampini      |  \/     \
1667e5337592SStefano Zampini      |   |      \
1668e5337592SStefano Zampini      |A  |   B   \
1669e5337592SStefano Zampini      |   0        \
1670e5337592SStefano Zampini      |   |         \
1671e5337592SStefano Zampini      0---0----------1
1672e5337592SStefano Zampini      */
1673e5337592SStefano Zampini     /* All cells have 4 faces */
1674e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
1675e5337592SStefano Zampini       const PetscInt  newp = cStartNew + (c - cStart)*3;
1676e5337592SStefano Zampini       const PetscInt *cone, *ornt;
1677e5337592SStefano Zampini       PetscInt        coneNew[4], orntNew[4];
1678e5337592SStefano Zampini 
1679e5337592SStefano Zampini       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1680e5337592SStefano Zampini       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1681e5337592SStefano Zampini       /* A quad */
1682e5337592SStefano Zampini       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
1683e5337592SStefano Zampini       orntNew[0] = ornt[0];
1684e5337592SStefano Zampini       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
1685e5337592SStefano Zampini       orntNew[1] = 0;
1686e5337592SStefano Zampini       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
1687e5337592SStefano Zampini       orntNew[2] = -2;
1688e5337592SStefano Zampini       coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
1689e5337592SStefano Zampini       orntNew[3] = ornt[2];
1690e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
1691e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
1692e5337592SStefano Zampini #if 1
1693e5337592SStefano 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);
1694e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
1695e5337592SStefano 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);
1696e5337592SStefano Zampini       }
1697e5337592SStefano Zampini #endif
1698e5337592SStefano Zampini       /* B quad */
1699e5337592SStefano Zampini       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
1700e5337592SStefano Zampini       orntNew[0] = ornt[0];
1701e5337592SStefano Zampini       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
1702e5337592SStefano Zampini       orntNew[1] = ornt[1];
1703e5337592SStefano Zampini       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
1704e5337592SStefano Zampini       orntNew[2] = 0;
1705e5337592SStefano Zampini       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
1706e5337592SStefano Zampini       orntNew[3] = -2;
1707e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
1708e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
1709e5337592SStefano Zampini #if 1
1710e5337592SStefano 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);
1711e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
1712e5337592SStefano 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);
1713e5337592SStefano Zampini       }
1714e5337592SStefano Zampini #endif
1715e5337592SStefano Zampini       /* C quad */
1716e5337592SStefano Zampini       coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
1717e5337592SStefano Zampini       orntNew[0] = ornt[1];
1718e5337592SStefano Zampini       coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
1719e5337592SStefano Zampini       orntNew[1] = ornt[2];
1720e5337592SStefano Zampini       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
1721e5337592SStefano Zampini       orntNew[2] = 0;
1722e5337592SStefano Zampini       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
1723e5337592SStefano Zampini       orntNew[3] = -2;
1724e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
1725e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
1726e5337592SStefano Zampini #if 1
1727e5337592SStefano 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);
1728e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
1729e5337592SStefano 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);
1730e5337592SStefano Zampini       }
1731e5337592SStefano Zampini #endif
1732e5337592SStefano Zampini     }
1733e5337592SStefano Zampini     /* Split faces have 2 vertices and the same cells as the parent */
1734e5337592SStefano Zampini     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1735e5337592SStefano Zampini     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
1736e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
1737e5337592SStefano Zampini       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
1738e5337592SStefano Zampini 
1739e5337592SStefano Zampini       for (r = 0; r < 2; ++r) {
1740e5337592SStefano Zampini         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1741e5337592SStefano Zampini         const PetscInt *cone, *ornt, *support;
1742e5337592SStefano Zampini         PetscInt        coneNew[2], coneSize, c, supportSize, s;
1743e5337592SStefano Zampini 
1744e5337592SStefano Zampini         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
1745e5337592SStefano Zampini         coneNew[0]       = vStartNew + (cone[0] - vStart);
1746e5337592SStefano Zampini         coneNew[1]       = vStartNew + (cone[1] - vStart);
1747e5337592SStefano Zampini         coneNew[(r+1)%2] = newv;
1748e5337592SStefano Zampini         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1749e5337592SStefano Zampini #if 1
1750e5337592SStefano Zampini         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1751e5337592SStefano Zampini         for (p = 0; p < 2; ++p) {
1752e5337592SStefano 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);
1753e5337592SStefano Zampini         }
1754e5337592SStefano Zampini #endif
1755e5337592SStefano Zampini         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
1756e5337592SStefano Zampini         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
1757e5337592SStefano Zampini         for (s = 0; s < supportSize; ++s) {
1758e5337592SStefano Zampini           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
1759e5337592SStefano Zampini           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1760e5337592SStefano Zampini           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
1761e5337592SStefano Zampini           for (c = 0; c < coneSize; ++c) {
1762e5337592SStefano Zampini             if (cone[c] == f) break;
1763e5337592SStefano Zampini           }
1764e5337592SStefano Zampini           supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
1765e5337592SStefano Zampini         }
1766e5337592SStefano Zampini         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
1767e5337592SStefano Zampini #if 1
1768e5337592SStefano Zampini         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1769e5337592SStefano Zampini         for (p = 0; p < supportSize; ++p) {
1770e5337592SStefano 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);
1771e5337592SStefano Zampini         }
1772e5337592SStefano Zampini #endif
1773e5337592SStefano Zampini       }
1774e5337592SStefano Zampini     }
1775e5337592SStefano Zampini     /* Interior faces have 2 vertices and 2 cells */
1776e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
1777e5337592SStefano Zampini       const PetscInt *cone;
1778e5337592SStefano Zampini 
1779e5337592SStefano Zampini       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1780e5337592SStefano Zampini       for (r = 0; r < 3; ++r) {
1781e5337592SStefano Zampini         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
1782e5337592SStefano Zampini         PetscInt       coneNew[2];
1783e5337592SStefano Zampini         PetscInt       supportNew[2];
1784e5337592SStefano Zampini 
1785e5337592SStefano Zampini         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
1786e5337592SStefano Zampini         coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd    - fStart) + (c - cStart);
1787e5337592SStefano Zampini         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1788e5337592SStefano Zampini #if 1
1789e5337592SStefano Zampini         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1790e5337592SStefano Zampini         for (p = 0; p < 2; ++p) {
1791e5337592SStefano 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);
1792e5337592SStefano Zampini         }
1793e5337592SStefano Zampini #endif
1794e5337592SStefano Zampini         supportNew[0] = (c - cStart)*3 + r%3;
1795e5337592SStefano Zampini         supportNew[1] = (c - cStart)*3 + (r+1)%3;
1796e5337592SStefano Zampini         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1797e5337592SStefano Zampini #if 1
1798e5337592SStefano Zampini         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1799e5337592SStefano Zampini         for (p = 0; p < 2; ++p) {
1800e5337592SStefano 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);
1801e5337592SStefano Zampini         }
1802e5337592SStefano Zampini #endif
1803e5337592SStefano Zampini       }
1804e5337592SStefano Zampini     }
1805e5337592SStefano Zampini     /* Old vertices have identical supports */
1806e5337592SStefano Zampini     for (v = vStart; v < vEnd; ++v) {
1807e5337592SStefano Zampini       const PetscInt  newp = vStartNew + (v - vStart);
1808e5337592SStefano Zampini       const PetscInt *support, *cone;
1809e5337592SStefano Zampini       PetscInt        size, s;
1810e5337592SStefano Zampini 
1811e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
1812e5337592SStefano Zampini       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
1813e5337592SStefano Zampini       for (s = 0; s < size; ++s) {
1814e5337592SStefano Zampini         PetscInt r = 0;
1815e5337592SStefano Zampini 
1816e5337592SStefano Zampini         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1817e5337592SStefano Zampini         if (cone[1] == v) r = 1;
1818e5337592SStefano Zampini         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
1819e5337592SStefano Zampini       }
1820e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
1821e5337592SStefano Zampini #if 1
1822e5337592SStefano Zampini       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
1823e5337592SStefano Zampini       for (p = 0; p < size; ++p) {
1824e5337592SStefano 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);
1825e5337592SStefano Zampini       }
1826e5337592SStefano Zampini #endif
1827e5337592SStefano Zampini     }
1828e5337592SStefano Zampini     /* Split-face vertices have cells + 2 supports */
1829e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
1830e5337592SStefano Zampini       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
1831e5337592SStefano Zampini       const PetscInt *cone, *support;
1832e5337592SStefano Zampini       PetscInt        size, s;
1833e5337592SStefano Zampini 
1834e5337592SStefano Zampini       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
1835e5337592SStefano Zampini       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
1836e5337592SStefano Zampini       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
1837e5337592SStefano Zampini       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
1838e5337592SStefano Zampini       for (s = 0; s < size; ++s) {
1839e5337592SStefano Zampini         PetscInt r = 0;
1840e5337592SStefano Zampini 
1841e5337592SStefano Zampini         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1842e5337592SStefano Zampini         if      (cone[1] == f) r = 1;
1843e5337592SStefano Zampini         else if (cone[2] == f) r = 2;
1844e5337592SStefano Zampini         supportRef[2+s+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
1845e5337592SStefano Zampini       }
1846e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
1847e5337592SStefano Zampini #if 1
1848e5337592SStefano Zampini       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
1849e5337592SStefano Zampini       for (p = 0; p < 2+size; ++p) {
1850e5337592SStefano 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);
1851e5337592SStefano Zampini       }
1852e5337592SStefano Zampini #endif
1853e5337592SStefano Zampini     }
1854e5337592SStefano Zampini     /* Interior vertices vertices have 3 supports */
1855e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
1856e5337592SStefano Zampini       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart;
1857e5337592SStefano Zampini 
1858e5337592SStefano Zampini       supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0;
1859e5337592SStefano Zampini       supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1;
1860e5337592SStefano Zampini       supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2;
1861e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
1862e5337592SStefano Zampini     }
1863e5337592SStefano Zampini     ierr = PetscFree(supportRef);CHKERRQ(ierr);
1864e5337592SStefano Zampini     break;
18659b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
186675d3a19aSMatthew G. Knepley     /*
186775d3a19aSMatthew G. Knepley      3---------2---------2
186875d3a19aSMatthew G. Knepley      |         |         |
186975d3a19aSMatthew G. Knepley      |    D    2    C    |
187075d3a19aSMatthew G. Knepley      |         |         |
187175d3a19aSMatthew G. Knepley      3----3----0----1----1
187275d3a19aSMatthew G. Knepley      |         |         |
187375d3a19aSMatthew G. Knepley      |    A    0    B    |
187475d3a19aSMatthew G. Knepley      |         |         |
187575d3a19aSMatthew G. Knepley      0---------0---------1
187675d3a19aSMatthew G. Knepley      */
187775d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
187875d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
187975d3a19aSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*4;
188075d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
188175d3a19aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
188275d3a19aSMatthew G. Knepley 
188375d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
188475d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
188575d3a19aSMatthew G. Knepley       /* A quad */
188675d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
188775d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
188875d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
188975d3a19aSMatthew G. Knepley       orntNew[1] = 0;
189075d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
189175d3a19aSMatthew G. Knepley       orntNew[2] = -2;
189275d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
189375d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
189475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
189575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
189675d3a19aSMatthew G. Knepley #if 1
189775d3a19aSMatthew 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);
189875d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
189975d3a19aSMatthew 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);
190075d3a19aSMatthew G. Knepley       }
190175d3a19aSMatthew G. Knepley #endif
190275d3a19aSMatthew G. Knepley       /* B quad */
190375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
190475d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
190575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
190675d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
190775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
1908efb27101SLisandro Dalcin       orntNew[2] = -2;
190975d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
191075d3a19aSMatthew G. Knepley       orntNew[3] = -2;
191175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
191275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
191375d3a19aSMatthew G. Knepley #if 1
191475d3a19aSMatthew 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);
191575d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
191675d3a19aSMatthew 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);
191775d3a19aSMatthew G. Knepley       }
191875d3a19aSMatthew G. Knepley #endif
191975d3a19aSMatthew G. Knepley       /* C quad */
192075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
1921efb27101SLisandro Dalcin       orntNew[0] = 0;
192275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
192375d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
192475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
192575d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
192675d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
1927efb27101SLisandro Dalcin       orntNew[3] = -2;
192875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
192975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
193075d3a19aSMatthew G. Knepley #if 1
193175d3a19aSMatthew 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);
193275d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
193375d3a19aSMatthew 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);
193475d3a19aSMatthew G. Knepley       }
193575d3a19aSMatthew G. Knepley #endif
193675d3a19aSMatthew G. Knepley       /* D quad */
193775d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
193875d3a19aSMatthew G. Knepley       orntNew[0] = 0;
193975d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
1940efb27101SLisandro Dalcin       orntNew[1] = 0;
194175d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
194275d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
194375d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
194475d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
194575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
194675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
194775d3a19aSMatthew G. Knepley #if 1
194875d3a19aSMatthew 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);
194975d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
195075d3a19aSMatthew 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);
195175d3a19aSMatthew G. Knepley       }
195275d3a19aSMatthew G. Knepley #endif
195375d3a19aSMatthew G. Knepley     }
195475d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
195575d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1956854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
195775d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
195875d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
195975d3a19aSMatthew G. Knepley 
196075d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
196175d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1962455d6cd4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
196375d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
196475d3a19aSMatthew G. Knepley 
196575d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
196675d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
196775d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
196875d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
196975d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
197075d3a19aSMatthew G. Knepley #if 1
197175d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
197275d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
197375d3a19aSMatthew 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);
197475d3a19aSMatthew G. Knepley         }
197575d3a19aSMatthew G. Knepley #endif
197675d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
197775d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
197875d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
197975d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
198075d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1981455d6cd4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
198275d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
198375d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
198475d3a19aSMatthew G. Knepley           }
1985455d6cd4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
198675d3a19aSMatthew G. Knepley         }
198775d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
198875d3a19aSMatthew G. Knepley #if 1
198975d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
199075d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
199175d3a19aSMatthew 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);
199275d3a19aSMatthew G. Knepley         }
199375d3a19aSMatthew G. Knepley #endif
199475d3a19aSMatthew G. Knepley       }
199575d3a19aSMatthew G. Knepley     }
199675d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
199775d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
199875d3a19aSMatthew G. Knepley       const PetscInt *cone;
199975d3a19aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
200075d3a19aSMatthew G. Knepley 
200175d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
200275d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
200375d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
200475d3a19aSMatthew G. Knepley 
2005efb27101SLisandro Dalcin 	if (r==1 || r==2) {
2006efb27101SLisandro Dalcin           coneNew[0] = vStartNew + (vEnd - vStart) + (fEnd    - fStart) + (c - cStart);
2007efb27101SLisandro Dalcin           coneNew[1] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2008efb27101SLisandro Dalcin 	} else {
200975d3a19aSMatthew G. Knepley           coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
201075d3a19aSMatthew G. Knepley           coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd    - fStart) + (c - cStart);
2011efb27101SLisandro Dalcin 	}
201275d3a19aSMatthew G. Knepley 	ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
201375d3a19aSMatthew G. Knepley #if 1
201475d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
201575d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
201675d3a19aSMatthew 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);
201775d3a19aSMatthew G. Knepley         }
201875d3a19aSMatthew G. Knepley #endif
201975d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
202075d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
202175d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
202275d3a19aSMatthew G. Knepley #if 1
202375d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
202475d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
202575d3a19aSMatthew 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);
202675d3a19aSMatthew G. Knepley         }
202775d3a19aSMatthew G. Knepley #endif
202875d3a19aSMatthew G. Knepley       }
202975d3a19aSMatthew G. Knepley     }
203075d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
203175d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
203275d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
203375d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
203475d3a19aSMatthew G. Knepley       PetscInt        size, s;
203575d3a19aSMatthew G. Knepley 
203675d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
203775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
203875d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
203975d3a19aSMatthew G. Knepley         PetscInt r = 0;
204075d3a19aSMatthew G. Knepley 
204175d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
204275d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
204375d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
204475d3a19aSMatthew G. Knepley       }
204575d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
204675d3a19aSMatthew G. Knepley #if 1
204775d3a19aSMatthew 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);
204875d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
204975d3a19aSMatthew 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);
205075d3a19aSMatthew G. Knepley       }
205175d3a19aSMatthew G. Knepley #endif
205275d3a19aSMatthew G. Knepley     }
205375d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
205475d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
205575d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
205675d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
205775d3a19aSMatthew G. Knepley       PetscInt        size, s;
205875d3a19aSMatthew G. Knepley 
205975d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
206075d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
206175d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
206275d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
206375d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
206475d3a19aSMatthew G. Knepley         PetscInt r = 0;
206575d3a19aSMatthew G. Knepley 
206675d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
206775d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
206875d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
206975d3a19aSMatthew G. Knepley         else if (cone[3] == f) r = 3;
207075d3a19aSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r;
207175d3a19aSMatthew G. Knepley       }
207275d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
207375d3a19aSMatthew G. Knepley #if 1
207475d3a19aSMatthew 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);
207575d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
207675d3a19aSMatthew 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);
207775d3a19aSMatthew G. Knepley       }
207875d3a19aSMatthew G. Knepley #endif
207975d3a19aSMatthew G. Knepley     }
208075d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
208175d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
208275d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
208375d3a19aSMatthew G. Knepley       PetscInt       supportNew[4];
208475d3a19aSMatthew G. Knepley 
208575d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
208675d3a19aSMatthew G. Knepley         supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
208775d3a19aSMatthew G. Knepley       }
208875d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
208975d3a19aSMatthew G. Knepley     }
2090da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
209175d3a19aSMatthew G. Knepley     break;
20929b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
209375d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
209475d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
209575d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
209675d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
2097149f48fdSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr);
209875d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
209975d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
210075d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
210175d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
210275d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
210375d3a19aSMatthew G. Knepley 
210475d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
210575d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
210675d3a19aSMatthew G. Knepley       /* A triangle */
210775d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
210875d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
210975d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
211075d3a19aSMatthew G. Knepley       orntNew[1] = -2;
211175d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
211275d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
211375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
211475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
211575d3a19aSMatthew G. Knepley #if 1
2116149f48fdSMatthew 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);
211775d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2118149f48fdSMatthew 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);
211975d3a19aSMatthew G. Knepley       }
212075d3a19aSMatthew G. Knepley #endif
212175d3a19aSMatthew G. Knepley       /* B triangle */
212275d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
212375d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
212475d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
212575d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
212675d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
212775d3a19aSMatthew G. Knepley       orntNew[2] = -2;
212875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
212975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
213075d3a19aSMatthew G. Knepley #if 1
2131a97b51b8SMatthew 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);
213275d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2133a97b51b8SMatthew 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);
213475d3a19aSMatthew G. Knepley       }
213575d3a19aSMatthew G. Knepley #endif
213675d3a19aSMatthew G. Knepley       /* C triangle */
213775d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
213875d3a19aSMatthew G. Knepley       orntNew[0] = -2;
213975d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
214075d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
214175d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
214275d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
214375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
214475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
214575d3a19aSMatthew G. Knepley #if 1
2146a97b51b8SMatthew 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);
214775d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2148a97b51b8SMatthew 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);
214975d3a19aSMatthew G. Knepley       }
215075d3a19aSMatthew G. Knepley #endif
215175d3a19aSMatthew G. Knepley       /* D triangle */
215275d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
215375d3a19aSMatthew G. Knepley       orntNew[0] = 0;
215475d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
215575d3a19aSMatthew G. Knepley       orntNew[1] = 0;
215675d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
215775d3a19aSMatthew G. Knepley       orntNew[2] = 0;
215875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
215975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
216075d3a19aSMatthew G. Knepley #if 1
2161a97b51b8SMatthew 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);
216275d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2163a97b51b8SMatthew 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);
216475d3a19aSMatthew G. Knepley       }
216575d3a19aSMatthew G. Knepley #endif
216675d3a19aSMatthew G. Knepley     }
216775d3a19aSMatthew G. Knepley     /*
216875d3a19aSMatthew G. Knepley      2----3----3
216975d3a19aSMatthew G. Knepley      |         |
217075d3a19aSMatthew G. Knepley      |    B    |
217175d3a19aSMatthew G. Knepley      |         |
217275d3a19aSMatthew G. Knepley      0----4--- 1
217375d3a19aSMatthew G. Knepley      |         |
217475d3a19aSMatthew G. Knepley      |    A    |
217575d3a19aSMatthew G. Knepley      |         |
217675d3a19aSMatthew G. Knepley      0----2----1
217775d3a19aSMatthew G. Knepley      */
217875d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
217975d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
218075d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
218175d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
2182ea00e70eSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4], r;
218375d3a19aSMatthew G. Knepley 
218475d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
218575d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2186ea00e70eSMatthew G. Knepley       r    = (ornt[0] < 0 ? 1 : 0);
218775d3a19aSMatthew G. Knepley       /* A quad */
2188ea00e70eSMatthew G. Knepley       coneNew[0]   = fStartNew + (cone[0] - fStart)*2 + r;
218975d3a19aSMatthew G. Knepley       orntNew[0]   = ornt[0];
2190ea00e70eSMatthew G. Knepley       coneNew[1]   = fStartNew + (cone[1] - fStart)*2 + r;
219175d3a19aSMatthew G. Knepley       orntNew[1]   = ornt[1];
2192ea00e70eSMatthew G. Knepley       coneNew[2+r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax);
2193ea00e70eSMatthew G. Knepley       orntNew[2+r] = 0;
2194ea00e70eSMatthew G. Knepley       coneNew[3-r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
2195ea00e70eSMatthew G. Knepley       orntNew[3-r] = 0;
219675d3a19aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
219775d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
219875d3a19aSMatthew G. Knepley #if 1
219975d3a19aSMatthew 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);
220075d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
220175d3a19aSMatthew 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);
220275d3a19aSMatthew G. Knepley       }
220375d3a19aSMatthew G. Knepley #endif
220475d3a19aSMatthew G. Knepley       /* B quad */
2205ea00e70eSMatthew G. Knepley       coneNew[0]   = fStartNew + (cone[0] - fStart)*2 + 1-r;
220675d3a19aSMatthew G. Knepley       orntNew[0]   = ornt[0];
2207ea00e70eSMatthew G. Knepley       coneNew[1]   = fStartNew + (cone[1] - fStart)*2 + 1-r;
220875d3a19aSMatthew G. Knepley       orntNew[1]   = ornt[1];
2209ea00e70eSMatthew G. Knepley       coneNew[2+r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
2210ea00e70eSMatthew G. Knepley       orntNew[2+r] = 0;
2211ea00e70eSMatthew G. Knepley       coneNew[3-r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax);
2212ea00e70eSMatthew G. Knepley       orntNew[3-r] = 0;
221375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
221475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
221575d3a19aSMatthew G. Knepley #if 1
221675d3a19aSMatthew 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);
221775d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
221875d3a19aSMatthew 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);
221975d3a19aSMatthew G. Knepley       }
222075d3a19aSMatthew G. Knepley #endif
222175d3a19aSMatthew G. Knepley     }
222275d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
222375d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2224854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
222575d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
222675d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
222775d3a19aSMatthew G. Knepley 
222875d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
222975d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
2230297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
223175d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
223275d3a19aSMatthew G. Knepley 
223375d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
223475d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
223575d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
223675d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
223775d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
223875d3a19aSMatthew G. Knepley #if 1
223975d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
224075d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
224175d3a19aSMatthew 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);
224275d3a19aSMatthew G. Knepley         }
224375d3a19aSMatthew G. Knepley #endif
224475d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
224575d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
224675d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
224775d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
224875d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2249297d2bf4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2250ea00e70eSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == f) break;
2251ea00e70eSMatthew G. Knepley           if (support[s] >= cMax) {
2252ea00e70eSMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r);
2253ea00e70eSMatthew G. Knepley           } else {
2254297d2bf4SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
225575d3a19aSMatthew G. Knepley           }
225675d3a19aSMatthew G. Knepley         }
225775d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
225875d3a19aSMatthew G. Knepley #if 1
225975d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
226075d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
226175d3a19aSMatthew 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);
226275d3a19aSMatthew G. Knepley         }
226375d3a19aSMatthew G. Knepley #endif
226475d3a19aSMatthew G. Knepley       }
226575d3a19aSMatthew G. Knepley     }
226675d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
226775d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
226875d3a19aSMatthew G. Knepley       const PetscInt *cone;
226975d3a19aSMatthew G. Knepley 
227075d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
227175d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
227275d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
227375d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
227475d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
227575d3a19aSMatthew G. Knepley 
227675d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
227775d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
227875d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
227975d3a19aSMatthew G. Knepley #if 1
228075d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
228175d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
228275d3a19aSMatthew 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);
228375d3a19aSMatthew G. Knepley         }
228475d3a19aSMatthew G. Knepley #endif
228575d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
228675d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
228775d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
228875d3a19aSMatthew G. Knepley #if 1
228975d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
229075d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
229175d3a19aSMatthew 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);
229275d3a19aSMatthew G. Knepley         }
229375d3a19aSMatthew G. Knepley #endif
229475d3a19aSMatthew G. Knepley       }
229575d3a19aSMatthew G. Knepley     }
229675d3a19aSMatthew G. Knepley     /* Interior hybrid faces have 2 vertices and the same cells */
229775d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
229875d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
2299ea00e70eSMatthew G. Knepley       const PetscInt *cone, *ornt;
230075d3a19aSMatthew G. Knepley       const PetscInt *support;
230175d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
230275d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
230375d3a19aSMatthew G. Knepley       PetscInt        size, s, r;
230475d3a19aSMatthew G. Knepley 
230575d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
230675d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
230775d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
230875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
230975d3a19aSMatthew G. Knepley #if 1
231075d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
231175d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
231275d3a19aSMatthew 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);
231375d3a19aSMatthew G. Knepley       }
231475d3a19aSMatthew G. Knepley #endif
231575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
231675d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
231775d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
231875d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2319ea00e70eSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
232075d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r) {
232175d3a19aSMatthew G. Knepley           if (cone[r+2] == f) break;
232275d3a19aSMatthew G. Knepley         }
2323ea00e70eSMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r);
232475d3a19aSMatthew G. Knepley       }
232575d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
232675d3a19aSMatthew G. Knepley #if 1
232775d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
232875d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
232975d3a19aSMatthew 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);
233075d3a19aSMatthew G. Knepley       }
233175d3a19aSMatthew G. Knepley #endif
233275d3a19aSMatthew G. Knepley     }
233375d3a19aSMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
233475d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
233575d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
233675d3a19aSMatthew G. Knepley       const PetscInt *cone;
233775d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
233875d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
233975d3a19aSMatthew G. Knepley 
234075d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
234175d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
234275d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
234375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
234475d3a19aSMatthew G. Knepley #if 1
234575d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
234675d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
234775d3a19aSMatthew 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);
234875d3a19aSMatthew G. Knepley       }
234975d3a19aSMatthew G. Knepley #endif
235075d3a19aSMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
235175d3a19aSMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
235275d3a19aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
235375d3a19aSMatthew G. Knepley #if 1
235475d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
235575d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
235675d3a19aSMatthew 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);
235775d3a19aSMatthew G. Knepley       }
235875d3a19aSMatthew G. Knepley #endif
235975d3a19aSMatthew G. Knepley     }
236075d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
236175d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
236275d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
236375d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
236475d3a19aSMatthew G. Knepley       PetscInt        size, s;
236575d3a19aSMatthew G. Knepley 
236675d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
236775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
236875d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
236975d3a19aSMatthew G. Knepley         if (support[s] >= fMax) {
237075d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax);
237175d3a19aSMatthew G. Knepley         } else {
237275d3a19aSMatthew G. Knepley           PetscInt r = 0;
237375d3a19aSMatthew G. Knepley 
237475d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
237575d3a19aSMatthew G. Knepley           if (cone[1] == v) r = 1;
237675d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
237775d3a19aSMatthew G. Knepley         }
237875d3a19aSMatthew G. Knepley       }
237975d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
238075d3a19aSMatthew G. Knepley #if 1
238175d3a19aSMatthew 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);
238275d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
238375d3a19aSMatthew 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);
238475d3a19aSMatthew G. Knepley       }
238575d3a19aSMatthew G. Knepley #endif
238675d3a19aSMatthew G. Knepley     }
238775d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
238875d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
238975d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
239075d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
239175d3a19aSMatthew G. Knepley       PetscInt        size, newSize = 2, s;
239275d3a19aSMatthew G. Knepley 
239375d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
239475d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
239575d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
239675d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
239775d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
239875d3a19aSMatthew G. Knepley         PetscInt r = 0;
239975d3a19aSMatthew G. Knepley 
240075d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
240175d3a19aSMatthew G. Knepley         if (support[s] >= cMax) {
240275d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax);
240375d3a19aSMatthew G. Knepley 
240475d3a19aSMatthew G. Knepley           newSize += 1;
240575d3a19aSMatthew G. Knepley         } else {
240675d3a19aSMatthew G. Knepley           if      (cone[1] == f) r = 1;
240775d3a19aSMatthew G. Knepley           else if (cone[2] == f) r = 2;
240875d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
240975d3a19aSMatthew G. Knepley           supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r;
241075d3a19aSMatthew G. Knepley 
241175d3a19aSMatthew G. Knepley           newSize += 2;
241275d3a19aSMatthew G. Knepley         }
241375d3a19aSMatthew G. Knepley       }
241475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
241575d3a19aSMatthew G. Knepley #if 1
241675d3a19aSMatthew 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);
241775d3a19aSMatthew G. Knepley       for (p = 0; p < newSize; ++p) {
241875d3a19aSMatthew 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);
241975d3a19aSMatthew G. Knepley       }
242075d3a19aSMatthew G. Knepley #endif
242175d3a19aSMatthew G. Knepley     }
242275d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
242375d3a19aSMatthew G. Knepley     break;
24249b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
2425a97b51b8SMatthew G. Knepley     /* Hybrid Hex 2D */
2426a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
2427a97b51b8SMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
2428a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
2429a97b51b8SMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
2430a97b51b8SMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr);
2431a97b51b8SMatthew G. Knepley     /* Interior cells have 4 faces */
2432a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
2433a97b51b8SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
2434a97b51b8SMatthew G. Knepley       const PetscInt *cone, *ornt;
2435a97b51b8SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
2436a97b51b8SMatthew G. Knepley 
2437a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2438a97b51b8SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2439a97b51b8SMatthew G. Knepley       /* A quad */
2440a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2441a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2442a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 0;
2443a97b51b8SMatthew G. Knepley       orntNew[1] = 0;
2444a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 3;
2445a97b51b8SMatthew G. Knepley       orntNew[2] = -2;
2446a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
2447a97b51b8SMatthew G. Knepley       orntNew[3] = ornt[3];
2448a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2449a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2450a97b51b8SMatthew G. Knepley #if 1
2451a97b51b8SMatthew 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);
2452a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2453a97b51b8SMatthew 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);
2454a97b51b8SMatthew G. Knepley       }
2455a97b51b8SMatthew G. Knepley #endif
2456a97b51b8SMatthew G. Knepley       /* B quad */
2457a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2458a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2459a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2460a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2461a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 1;
2462a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
2463a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 0;
2464a97b51b8SMatthew G. Knepley       orntNew[3] = -2;
2465a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2466a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2467a97b51b8SMatthew G. Knepley #if 1
2468a97b51b8SMatthew 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);
2469a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2470a97b51b8SMatthew 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);
2471a97b51b8SMatthew G. Knepley       }
2472a97b51b8SMatthew G. Knepley #endif
2473a97b51b8SMatthew G. Knepley       /* C quad */
2474a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 1;
2475a97b51b8SMatthew G. Knepley       orntNew[0] = -2;
2476a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2477a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2478a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
2479a97b51b8SMatthew G. Knepley       orntNew[2] = ornt[2];
2480a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 2;
2481a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
2482a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2483a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2484a97b51b8SMatthew G. Knepley #if 1
2485a97b51b8SMatthew 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);
2486a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2487a97b51b8SMatthew 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);
2488a97b51b8SMatthew G. Knepley       }
2489a97b51b8SMatthew G. Knepley #endif
2490a97b51b8SMatthew G. Knepley       /* D quad */
2491a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 3;
2492a97b51b8SMatthew G. Knepley       orntNew[0] = 0;
2493a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 2;
2494a97b51b8SMatthew G. Knepley       orntNew[1] = -2;
2495a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
2496a97b51b8SMatthew G. Knepley       orntNew[2] = ornt[2];
2497a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
2498a97b51b8SMatthew G. Knepley       orntNew[3] = ornt[3];
2499a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2500a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2501a97b51b8SMatthew G. Knepley #if 1
2502a97b51b8SMatthew 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);
2503a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2504a97b51b8SMatthew 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);
2505a97b51b8SMatthew G. Knepley       }
2506a97b51b8SMatthew G. Knepley #endif
2507a97b51b8SMatthew G. Knepley     }
2508a97b51b8SMatthew G. Knepley     /*
2509a97b51b8SMatthew G. Knepley      2----3----3
2510a97b51b8SMatthew G. Knepley      |         |
2511a97b51b8SMatthew G. Knepley      |    B    |
2512a97b51b8SMatthew G. Knepley      |         |
2513a97b51b8SMatthew G. Knepley      0----4--- 1
2514a97b51b8SMatthew G. Knepley      |         |
2515a97b51b8SMatthew G. Knepley      |    A    |
2516a97b51b8SMatthew G. Knepley      |         |
2517a97b51b8SMatthew G. Knepley      0----2----1
2518a97b51b8SMatthew G. Knepley      */
2519a97b51b8SMatthew G. Knepley     /* Hybrid cells have 4 faces */
2520a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
2521a97b51b8SMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
2522a97b51b8SMatthew G. Knepley       const PetscInt *cone, *ornt;
2523a97b51b8SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
2524a97b51b8SMatthew G. Knepley 
2525a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2526a97b51b8SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2527a97b51b8SMatthew G. Knepley       /* A quad */
2528a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2529a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2530a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2531a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2532a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax);
2533a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
2534a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (fEnd    - fMax) + (c - cMax);
2535a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
2536a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2537a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2538a97b51b8SMatthew G. Knepley #if 1
2539a97b51b8SMatthew 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);
2540a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2541a97b51b8SMatthew 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);
2542a97b51b8SMatthew G. Knepley       }
2543a97b51b8SMatthew G. Knepley #endif
2544a97b51b8SMatthew G. Knepley       /* B quad */
2545a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2546a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2547a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2548a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2549a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (fEnd    - fMax) + (c - cMax);
2550a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
2551a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax);
2552a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
2553a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2554a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2555a97b51b8SMatthew G. Knepley #if 1
2556a97b51b8SMatthew 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);
2557a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2558a97b51b8SMatthew 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);
2559a97b51b8SMatthew G. Knepley       }
2560a97b51b8SMatthew G. Knepley #endif
2561a97b51b8SMatthew G. Knepley     }
2562a97b51b8SMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
2563a97b51b8SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2564854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
2565a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
2566a97b51b8SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
2567a97b51b8SMatthew G. Knepley 
2568a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
2569a97b51b8SMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
2570a97b51b8SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
2571a97b51b8SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
2572a97b51b8SMatthew G. Knepley 
2573a97b51b8SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2574a97b51b8SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
2575a97b51b8SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
2576a97b51b8SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
2577a97b51b8SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2578a97b51b8SMatthew G. Knepley #if 1
2579a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2580a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2581a97b51b8SMatthew 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);
2582a97b51b8SMatthew G. Knepley         }
2583a97b51b8SMatthew G. Knepley #endif
2584a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2585a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2586a97b51b8SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2587a97b51b8SMatthew G. Knepley           if (support[s] >= cMax) {
2588a97b51b8SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
2589a97b51b8SMatthew G. Knepley           } else {
2590a97b51b8SMatthew G. Knepley             ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2591a97b51b8SMatthew G. Knepley             ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2592a97b51b8SMatthew G. Knepley             ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2593a97b51b8SMatthew G. Knepley             for (c = 0; c < coneSize; ++c) {
2594a97b51b8SMatthew G. Knepley               if (cone[c] == f) break;
2595a97b51b8SMatthew G. Knepley             }
2596a97b51b8SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
2597a97b51b8SMatthew G. Knepley           }
2598a97b51b8SMatthew G. Knepley         }
2599a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2600a97b51b8SMatthew G. Knepley #if 1
2601a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2602a97b51b8SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2603a97b51b8SMatthew 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);
2604a97b51b8SMatthew G. Knepley         }
2605a97b51b8SMatthew G. Knepley #endif
2606a97b51b8SMatthew G. Knepley       }
2607a97b51b8SMatthew G. Knepley     }
2608a97b51b8SMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
2609a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
2610a97b51b8SMatthew G. Knepley       const PetscInt *cone;
2611a97b51b8SMatthew G. Knepley 
2612a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2613a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2614a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
2615a97b51b8SMatthew G. Knepley         PetscInt       coneNew[2], supportNew[2];
2616a97b51b8SMatthew G. Knepley 
2617a97b51b8SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2618a97b51b8SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fMax    - fStart) + (c - cStart);
2619a97b51b8SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2620a97b51b8SMatthew G. Knepley #if 1
2621a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2622a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2623a97b51b8SMatthew 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);
2624a97b51b8SMatthew G. Knepley         }
2625a97b51b8SMatthew G. Knepley #endif
2626a97b51b8SMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
2627a97b51b8SMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
2628a97b51b8SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2629a97b51b8SMatthew G. Knepley #if 1
2630a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2631a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2632a97b51b8SMatthew 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);
2633a97b51b8SMatthew G. Knepley         }
2634a97b51b8SMatthew G. Knepley #endif
2635a97b51b8SMatthew G. Knepley       }
2636a97b51b8SMatthew G. Knepley     }
2637a97b51b8SMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
2638a97b51b8SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
2639a97b51b8SMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
2640a97b51b8SMatthew G. Knepley       const PetscInt *cone, *support;
2641a97b51b8SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
2642a97b51b8SMatthew G. Knepley       PetscInt        size, s, r;
2643a97b51b8SMatthew G. Knepley 
2644a97b51b8SMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2645a97b51b8SMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
2646a97b51b8SMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
2647a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2648a97b51b8SMatthew G. Knepley #if 1
2649a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2650a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2651a97b51b8SMatthew 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);
2652a97b51b8SMatthew G. Knepley       }
2653a97b51b8SMatthew G. Knepley #endif
2654a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
2655a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2656a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2657a97b51b8SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2658a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r) {
2659a97b51b8SMatthew G. Knepley           if (cone[r+2] == f) break;
2660a97b51b8SMatthew G. Knepley         }
2661a97b51b8SMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
2662a97b51b8SMatthew G. Knepley       }
2663a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2664a97b51b8SMatthew G. Knepley #if 1
2665a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2666a97b51b8SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2667a97b51b8SMatthew 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);
2668a97b51b8SMatthew G. Knepley       }
2669a97b51b8SMatthew G. Knepley #endif
2670a97b51b8SMatthew G. Knepley     }
2671a97b51b8SMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
2672a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
2673a97b51b8SMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
2674a97b51b8SMatthew G. Knepley       const PetscInt *cone;
2675a97b51b8SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
2676a97b51b8SMatthew G. Knepley 
2677a97b51b8SMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2678a97b51b8SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
2679a97b51b8SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
2680a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2681a97b51b8SMatthew G. Knepley #if 1
2682a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2683a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2684a97b51b8SMatthew 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);
2685a97b51b8SMatthew G. Knepley       }
2686a97b51b8SMatthew G. Knepley #endif
2687a97b51b8SMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
2688a97b51b8SMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
2689a97b51b8SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2690a97b51b8SMatthew G. Knepley #if 1
2691a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2692a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2693a97b51b8SMatthew 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);
2694a97b51b8SMatthew G. Knepley       }
2695a97b51b8SMatthew G. Knepley #endif
2696a97b51b8SMatthew G. Knepley     }
2697a97b51b8SMatthew G. Knepley     /* Old vertices have identical supports */
2698a97b51b8SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
2699a97b51b8SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
2700a97b51b8SMatthew G. Knepley       const PetscInt *support, *cone;
2701a97b51b8SMatthew G. Knepley       PetscInt        size, s;
2702a97b51b8SMatthew G. Knepley 
2703a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
2704a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
2705a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2706a97b51b8SMatthew G. Knepley         if (support[s] >= fMax) {
2707a97b51b8SMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax);
2708a97b51b8SMatthew G. Knepley         } else {
2709a97b51b8SMatthew G. Knepley           PetscInt r = 0;
2710a97b51b8SMatthew G. Knepley 
2711a97b51b8SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2712a97b51b8SMatthew G. Knepley           if (cone[1] == v) r = 1;
2713a97b51b8SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
2714a97b51b8SMatthew G. Knepley         }
2715a97b51b8SMatthew G. Knepley       }
2716a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2717a97b51b8SMatthew G. Knepley #if 1
2718a97b51b8SMatthew 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);
2719a97b51b8SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2720a97b51b8SMatthew 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);
2721a97b51b8SMatthew G. Knepley       }
2722a97b51b8SMatthew G. Knepley #endif
2723a97b51b8SMatthew G. Knepley     }
2724a97b51b8SMatthew G. Knepley     /* Face vertices have 2 + cells supports */
2725a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
2726a97b51b8SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
2727a97b51b8SMatthew G. Knepley       const PetscInt *cone, *support;
2728a97b51b8SMatthew G. Knepley       PetscInt        size, s;
2729a97b51b8SMatthew G. Knepley 
2730a97b51b8SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
2731a97b51b8SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2732a97b51b8SMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
2733a97b51b8SMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
2734a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2735a97b51b8SMatthew G. Knepley         PetscInt r = 0;
2736a97b51b8SMatthew G. Knepley 
2737a97b51b8SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2738a97b51b8SMatthew G. Knepley         if (support[s] >= cMax) {
2739a97b51b8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax);
2740a97b51b8SMatthew G. Knepley         } else {
2741a97b51b8SMatthew G. Knepley           if      (cone[1] == f) r = 1;
2742a97b51b8SMatthew G. Knepley           else if (cone[2] == f) r = 2;
2743a97b51b8SMatthew G. Knepley           else if (cone[3] == f) r = 3;
2744a97b51b8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r;
2745a97b51b8SMatthew G. Knepley         }
2746a97b51b8SMatthew G. Knepley       }
2747a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2748a97b51b8SMatthew G. Knepley #if 1
2749a97b51b8SMatthew 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);
2750a97b51b8SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
2751a97b51b8SMatthew 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);
2752a97b51b8SMatthew G. Knepley       }
2753a97b51b8SMatthew G. Knepley #endif
2754a97b51b8SMatthew G. Knepley     }
2755a97b51b8SMatthew G. Knepley     /* Cell vertices have 4 supports */
2756a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
2757a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
2758a97b51b8SMatthew G. Knepley       PetscInt       supportNew[4];
2759a97b51b8SMatthew G. Knepley 
2760a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2761a97b51b8SMatthew G. Knepley         supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
2762a97b51b8SMatthew G. Knepley       }
2763a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2764a97b51b8SMatthew G. Knepley     }
2765a97b51b8SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
2766a97b51b8SMatthew G. Knepley     break;
27679b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
2768b5da9499SMatthew G. Knepley     /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
2769b5da9499SMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
2770b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2771b5da9499SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
2772b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
2773b5da9499SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
2774b5da9499SMatthew G. Knepley 
2775b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2776b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2777b5da9499SMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
2778518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
2779b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2780518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
2781b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2782518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
2783b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2784b5da9499SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
2785b5da9499SMatthew G. Knepley       orntNew[3] = 0;
2786b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2787b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2788b5da9499SMatthew G. Knepley #if 1
2789b5da9499SMatthew 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);
2790b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2791b5da9499SMatthew 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);
2792b5da9499SMatthew G. Knepley       }
2793b5da9499SMatthew G. Knepley #endif
2794b5da9499SMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
2795518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
2796b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2797518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
2798b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2799b5da9499SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
2800b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2801518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
2802b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2803b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2804b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2805b5da9499SMatthew G. Knepley #if 1
2806b5da9499SMatthew 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);
2807b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2808b5da9499SMatthew 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);
2809b5da9499SMatthew G. Knepley       }
2810b5da9499SMatthew G. Knepley #endif
2811b5da9499SMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
2812518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
2813b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2814b5da9499SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
2815b5da9499SMatthew G. Knepley       orntNew[1] = 0;
2816518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
2817b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2818518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
2819b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2820b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2821b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2822b5da9499SMatthew G. Knepley #if 1
2823b5da9499SMatthew 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);
2824b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2825b5da9499SMatthew 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);
2826b5da9499SMatthew G. Knepley       }
2827b5da9499SMatthew G. Knepley #endif
2828b5da9499SMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
2829b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
2830b5da9499SMatthew G. Knepley       orntNew[0] = 0;
2831518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
2832b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2833518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
2834b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2835518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
2836b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2837b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2838b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2839b5da9499SMatthew G. Knepley #if 1
2840b5da9499SMatthew 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);
2841b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2842b5da9499SMatthew 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);
2843b5da9499SMatthew G. Knepley       }
2844b5da9499SMatthew G. Knepley #endif
28453fe31fa2SToby Isaac       /* A' tetrahedron: {c, d, a, f} */
2846b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
2847b5da9499SMatthew G. Knepley       orntNew[0] = -3;
2848fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
2849e5337592SStefano Zampini       orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0);
2850fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
2851fac4ab25SMatthew G. Knepley       orntNew[2] = 0;
2852fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
2853fac4ab25SMatthew G. Knepley       orntNew[3] = 2;
2854b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
2855b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
2856b5da9499SMatthew G. Knepley #if 1
2857b5da9499SMatthew 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);
2858b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2859b5da9499SMatthew 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);
2860b5da9499SMatthew G. Knepley       }
2861b5da9499SMatthew G. Knepley #endif
2862b5da9499SMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
2863b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
28643fe31fa2SToby Isaac       orntNew[0] = -2;
28653fe31fa2SToby Isaac       coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3;
2866e5337592SStefano Zampini       orntNew[1] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 1)+1) : GetTriMidEdge_Static(ornt[3], 1);
28673fe31fa2SToby Isaac       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
2868b5da9499SMatthew G. Knepley       orntNew[2] = 0;
28693fe31fa2SToby Isaac       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
28703fe31fa2SToby Isaac       orntNew[3] = 0;
2871b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
2872b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
2873b5da9499SMatthew G. Knepley #if 1
2874b5da9499SMatthew 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);
2875b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2876b5da9499SMatthew 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);
2877b5da9499SMatthew G. Knepley       }
2878b5da9499SMatthew G. Knepley #endif
28793fe31fa2SToby Isaac       /* C' tetrahedron: {f, a, c, b} */
28803fe31fa2SToby Isaac       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
28813fe31fa2SToby Isaac       orntNew[0] = -2;
28823fe31fa2SToby Isaac       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
28833fe31fa2SToby Isaac       orntNew[1] = -2;
28843fe31fa2SToby Isaac       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
28853fe31fa2SToby Isaac       orntNew[2] = -1;
28863fe31fa2SToby Isaac       coneNew[3] = fStartNew + (cone[0] - fStart)*4 + 3;
2887e5337592SStefano Zampini       orntNew[3] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2);
2888b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
2889b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
2890b5da9499SMatthew G. Knepley #if 1
2891b5da9499SMatthew 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);
2892b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2893b5da9499SMatthew 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);
2894b5da9499SMatthew G. Knepley       }
2895b5da9499SMatthew G. Knepley #endif
28963fe31fa2SToby Isaac       /* D' tetrahedron: {f, a, e, d} */
28973fe31fa2SToby Isaac       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
28983fe31fa2SToby Isaac       orntNew[0] = -2;
2899fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
29003fe31fa2SToby Isaac       orntNew[1] = -1;
29013fe31fa2SToby Isaac       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
29023fe31fa2SToby Isaac       orntNew[2] = -2;
29033fe31fa2SToby Isaac       coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3;
2904e5337592SStefano Zampini       orntNew[3] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 1)+1) : GetTriMidEdge_Static(ornt[1], 1);
2905b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
2906b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
2907b5da9499SMatthew G. Knepley #if 1
2908b5da9499SMatthew 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);
2909b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2910b5da9499SMatthew 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);
2911b5da9499SMatthew G. Knepley       }
2912b5da9499SMatthew G. Knepley #endif
2913b5da9499SMatthew G. Knepley     }
2914b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
2915b5da9499SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2916854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
2917b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
2918b5da9499SMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
2919b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
2920b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
2921b5da9499SMatthew G. Knepley 
2922b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2923b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
2924b5da9499SMatthew G. Knepley       /* A triangle */
2925b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
2926b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2927b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
2928b5da9499SMatthew G. Knepley       orntNew[1] = -2;
2929b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
2930b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2931b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2932b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2933b5da9499SMatthew G. Knepley #if 1
2934b5da9499SMatthew 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);
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       /* B triangle */
2940b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
2941b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2942b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
2943b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2944b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
2945b5da9499SMatthew G. Knepley       orntNew[2] = -2;
2946b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2947b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2948b5da9499SMatthew G. Knepley #if 1
2949b5da9499SMatthew 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);
2950b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2951b5da9499SMatthew 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);
2952b5da9499SMatthew G. Knepley       }
2953b5da9499SMatthew G. Knepley #endif
2954b5da9499SMatthew G. Knepley       /* C triangle */
2955b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
2956b5da9499SMatthew G. Knepley       orntNew[0] = -2;
2957b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
2958b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2959b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
2960b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2961b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2962b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2963b5da9499SMatthew G. Knepley #if 1
2964b5da9499SMatthew 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);
2965b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2966b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2967b5da9499SMatthew G. Knepley       }
2968b5da9499SMatthew G. Knepley #endif
2969b5da9499SMatthew G. Knepley       /* D triangle */
2970b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
2971b5da9499SMatthew G. Knepley       orntNew[0] = 0;
2972b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
2973b5da9499SMatthew G. Knepley       orntNew[1] = 0;
2974b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
2975b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2976b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2977b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2978b5da9499SMatthew G. Knepley #if 1
2979b5da9499SMatthew 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);
2980b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2981b5da9499SMatthew 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);
2982b5da9499SMatthew G. Knepley       }
2983b5da9499SMatthew G. Knepley #endif
2984b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2985b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2986b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2987b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2988219f7b90SMatthew G. Knepley           PetscInt subf;
2989b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2990b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2991b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2992b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
2993b5da9499SMatthew G. Knepley             if (cone[c] == f) break;
2994b5da9499SMatthew G. Knepley           }
2995219f7b90SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
2996219f7b90SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
2997b5da9499SMatthew G. Knepley         }
2998b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
2999b5da9499SMatthew G. Knepley #if 1
30009ddff745SMatthew 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);
3001b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
3002b5da9499SMatthew 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);
3003b5da9499SMatthew G. Knepley         }
3004b5da9499SMatthew G. Knepley #endif
3005b5da9499SMatthew G. Knepley       }
3006b5da9499SMatthew G. Knepley     }
3007b5da9499SMatthew G. Knepley     /* Interior faces have 3 edges and 2 cells */
3008b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
3009b5da9499SMatthew G. Knepley       PetscInt        newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8;
3010b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
3011b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
3012b5da9499SMatthew G. Knepley       PetscInt        supportNew[2];
3013b5da9499SMatthew G. Knepley 
3014b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
3015b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
3016b5da9499SMatthew G. Knepley       /* Face A: {c, a, d} */
3017e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
3018b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
3019e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
3020b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
3021e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2);
3022b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
3023b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3024b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3025b5da9499SMatthew G. Knepley #if 1
3026b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3027b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
3028b5da9499SMatthew 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);
3029b5da9499SMatthew G. Knepley       }
3030b5da9499SMatthew G. Knepley #endif
3031b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
3032b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
3033b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3034b5da9499SMatthew G. Knepley #if 1
3035b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3036b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3037b5da9499SMatthew 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);
3038b5da9499SMatthew G. Knepley       }
3039b5da9499SMatthew G. Knepley #endif
3040b5da9499SMatthew G. Knepley       ++newp;
3041b5da9499SMatthew G. Knepley       /* Face B: {a, b, e} */
3042e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
3043b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
3044e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0);
3045b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
3046e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
3047b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
3048b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3049b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3050b5da9499SMatthew G. Knepley #if 1
30514bb260e2SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3052b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
3053b5da9499SMatthew 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);
3054b5da9499SMatthew G. Knepley       }
3055b5da9499SMatthew G. Knepley #endif
3056b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
3057b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
3058b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3059b5da9499SMatthew G. Knepley #if 1
3060b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3061b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3062b5da9499SMatthew 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);
3063b5da9499SMatthew G. Knepley       }
3064b5da9499SMatthew G. Knepley #endif
3065b5da9499SMatthew G. Knepley       ++newp;
3066b5da9499SMatthew G. Knepley       /* Face C: {c, f, b} */
3067e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
3068b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
3069e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
3070b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
3071e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1);
3072b5da9499SMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
3073b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3074b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3075b5da9499SMatthew G. Knepley #if 1
3076b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3077b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
3078b5da9499SMatthew 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);
3079b5da9499SMatthew G. Knepley       }
3080b5da9499SMatthew G. Knepley #endif
3081b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
3082b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
3083b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3084b5da9499SMatthew G. Knepley #if 1
3085b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3086b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3087b5da9499SMatthew 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);
3088b5da9499SMatthew G. Knepley       }
3089b5da9499SMatthew G. Knepley #endif
3090b5da9499SMatthew G. Knepley       ++newp;
3091b5da9499SMatthew G. Knepley       /* Face D: {d, e, f} */
3092e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0);
3093b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
3094e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
3095b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
3096e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
3097b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
3098b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3099b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3100b5da9499SMatthew G. Knepley #if 1
3101b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3102b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
3103b5da9499SMatthew 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);
3104b5da9499SMatthew G. Knepley       }
3105b5da9499SMatthew G. Knepley #endif
3106b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
3107b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
3108b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3109b5da9499SMatthew G. Knepley #if 1
3110b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3111b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3112b5da9499SMatthew 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);
3113b5da9499SMatthew G. Knepley       }
3114b5da9499SMatthew G. Knepley #endif
3115b5da9499SMatthew G. Knepley       ++newp;
3116b5da9499SMatthew G. Knepley       /* Face E: {d, f, a} */
3117e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
3118b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
3119b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
31204bb260e2SMatthew G. Knepley       orntNew[1] = -2;
3121e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
3122b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
3123b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3124b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3125b5da9499SMatthew G. Knepley #if 1
3126b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3127b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
3128b5da9499SMatthew 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);
3129b5da9499SMatthew G. Knepley       }
3130b5da9499SMatthew G. Knepley #endif
3131b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
3132b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
3133b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3134b5da9499SMatthew G. Knepley #if 1
3135b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3136b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3137b5da9499SMatthew 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);
3138b5da9499SMatthew G. Knepley       }
3139b5da9499SMatthew G. Knepley #endif
3140b5da9499SMatthew G. Knepley       ++newp;
3141b5da9499SMatthew G. Knepley       /* Face F: {c, a, f} */
3142e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
3143b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
3144b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
31454bb260e2SMatthew G. Knepley       orntNew[1] = 0;
3146e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
31472baf2947SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
3148b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3149b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3150b5da9499SMatthew G. Knepley #if 1
3151b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3152b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
3153b5da9499SMatthew 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);
3154b5da9499SMatthew G. Knepley       }
3155b5da9499SMatthew G. Knepley #endif
3156b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
3157b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
3158b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3159b5da9499SMatthew G. Knepley #if 1
3160b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3161b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3162b5da9499SMatthew 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);
3163b5da9499SMatthew G. Knepley       }
3164b5da9499SMatthew G. Knepley #endif
3165b5da9499SMatthew G. Knepley       ++newp;
3166b5da9499SMatthew G. Knepley       /* Face G: {e, a, f} */
3167e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
3168b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
3169b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
3170fac4ab25SMatthew G. Knepley       orntNew[1] = 0;
3171e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
3172b5da9499SMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
3173b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3174b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3175b5da9499SMatthew G. Knepley #if 1
3176b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3177b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
3178b5da9499SMatthew 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);
3179b5da9499SMatthew G. Knepley       }
3180b5da9499SMatthew G. Knepley #endif
3181b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
3182b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
3183b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3184b5da9499SMatthew G. Knepley #if 1
3185b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3186b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3187b5da9499SMatthew 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);
3188b5da9499SMatthew G. Knepley       }
3189b5da9499SMatthew G. Knepley #endif
3190b5da9499SMatthew G. Knepley       ++newp;
3191b5da9499SMatthew G. Knepley       /* Face H: {a, b, f} */
3192e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
3193b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
3194e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
3195b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
3196b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
31974bb260e2SMatthew G. Knepley       orntNew[2] = -2;
3198b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3199b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3200b5da9499SMatthew G. Knepley #if 1
3201b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3202b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
3203b5da9499SMatthew 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);
3204b5da9499SMatthew G. Knepley       }
3205b5da9499SMatthew G. Knepley #endif
3206b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
3207b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
3208b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3209b5da9499SMatthew G. Knepley #if 1
3210b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3211b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3212b5da9499SMatthew 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);
3213b5da9499SMatthew G. Knepley       }
3214b5da9499SMatthew G. Knepley #endif
3215b5da9499SMatthew G. Knepley       ++newp;
3216b5da9499SMatthew G. Knepley     }
3217b5da9499SMatthew G. Knepley     /* Split Edges have 2 vertices and the same faces as the parent */
3218b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
3219b5da9499SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
3220b5da9499SMatthew G. Knepley 
3221b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
3222b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
3223b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
3224b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
3225b5da9499SMatthew G. Knepley 
3226b5da9499SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
3227b5da9499SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
3228b5da9499SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
3229b5da9499SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
3230b5da9499SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3231b5da9499SMatthew G. Knepley #if 1
3232b5da9499SMatthew 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);
3233b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
3234b5da9499SMatthew 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);
3235b5da9499SMatthew G. Knepley         }
3236b5da9499SMatthew G. Knepley #endif
3237b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
3238b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
3239b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
3240b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
3241b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
3242b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
3243b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
3244b5da9499SMatthew G. Knepley             if (cone[c] == e) break;
3245b5da9499SMatthew G. Knepley           }
3246b5da9499SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
3247b5da9499SMatthew G. Knepley         }
3248b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
3249b5da9499SMatthew G. Knepley #if 1
3250b5da9499SMatthew 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);
3251b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
3252b5da9499SMatthew 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);
3253b5da9499SMatthew G. Knepley         }
3254b5da9499SMatthew G. Knepley #endif
3255b5da9499SMatthew G. Knepley       }
3256b5da9499SMatthew G. Knepley     }
325786f0afeeSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
3258b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
3259b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
3260b5da9499SMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
3261b5da9499SMatthew G. Knepley 
3262b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
3263b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
3264b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
3265b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
3266b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
3267b5da9499SMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
3268b5da9499SMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
3269b5da9499SMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
3270b5da9499SMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
3271b5da9499SMatthew G. Knepley 
3272b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
3273b5da9499SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
3274b5da9499SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
3275b5da9499SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3276b5da9499SMatthew G. Knepley #if 1
3277b5da9499SMatthew 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);
3278b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
3279b5da9499SMatthew 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);
3280b5da9499SMatthew G. Knepley         }
3281b5da9499SMatthew G. Knepley #endif
3282b5da9499SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
3283b5da9499SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
3284b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
3285b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
3286b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
3287b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
3288b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
328986f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
3290e5337592SStefano Zampini           er = GetTriMidEdgeInverse_Static(ornt[c], r);
3291b5da9499SMatthew G. Knepley           if (er == eint[c]) {
3292b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
3293b5da9499SMatthew G. Knepley           } else {
3294b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
3295b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
3296b5da9499SMatthew G. Knepley           }
3297b5da9499SMatthew G. Knepley         }
3298b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
3299b5da9499SMatthew G. Knepley #if 1
3300b5da9499SMatthew 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);
3301b5da9499SMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
3302b5da9499SMatthew 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);
3303b5da9499SMatthew G. Knepley         }
3304b5da9499SMatthew G. Knepley #endif
3305b5da9499SMatthew G. Knepley       }
3306b5da9499SMatthew G. Knepley     }
3307b5da9499SMatthew G. Knepley     /* Interior edges have 2 vertices and 4 faces */
3308b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
3309b5da9499SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
3310b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
33114a40f731SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
3312b5da9499SMatthew G. Knepley 
3313b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
3314b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
3315b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
331642525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
3317b5da9499SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
3318b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
331942525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
3320b5da9499SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
3321b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3322b5da9499SMatthew G. Knepley #if 1
3323b5da9499SMatthew 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);
3324b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
3325b5da9499SMatthew 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);
3326b5da9499SMatthew G. Knepley       }
3327b5da9499SMatthew G. Knepley #endif
3328b5da9499SMatthew G. Knepley       supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
3329b5da9499SMatthew G. Knepley       supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
3330b5da9499SMatthew G. Knepley       supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
3331b5da9499SMatthew G. Knepley       supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
3332b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
3333b5da9499SMatthew G. Knepley #if 1
3334b5da9499SMatthew 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);
3335b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3336b5da9499SMatthew 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);
3337b5da9499SMatthew G. Knepley       }
3338b5da9499SMatthew G. Knepley #endif
3339b5da9499SMatthew G. Knepley     }
3340b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
3341b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
3342b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
3343b5da9499SMatthew G. Knepley       const PetscInt *support, *cone;
3344b5da9499SMatthew G. Knepley       PetscInt        size, s;
3345b5da9499SMatthew G. Knepley 
3346b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
3347b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
3348b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
3349b5da9499SMatthew G. Knepley         PetscInt r = 0;
3350b5da9499SMatthew G. Knepley 
3351b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
3352b5da9499SMatthew G. Knepley         if (cone[1] == v) r = 1;
3353b5da9499SMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
3354b5da9499SMatthew G. Knepley       }
3355b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
3356b5da9499SMatthew G. Knepley #if 1
3357b5da9499SMatthew 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);
3358b5da9499SMatthew G. Knepley       for (p = 0; p < size; ++p) {
3359b5da9499SMatthew 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);
3360b5da9499SMatthew G. Knepley       }
3361b5da9499SMatthew G. Knepley #endif
3362b5da9499SMatthew G. Knepley     }
3363b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + face*2 + 0/1 supports */
3364b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
3365b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
3366b5da9499SMatthew G. Knepley       const PetscInt *cone, *support;
3367b5da9499SMatthew G. Knepley       PetscInt       *star = NULL, starSize, cellSize = 0, coneSize, size, s;
3368b5da9499SMatthew G. Knepley 
3369b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
3370b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
3371b5da9499SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
3372b5da9499SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
3373b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
3374b5da9499SMatthew G. Knepley         PetscInt r = 0;
3375b5da9499SMatthew G. Knepley 
3376b5da9499SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
3377b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
3378b5da9499SMatthew G. Knepley         for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
3379b5da9499SMatthew G. Knepley         supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
3380b5da9499SMatthew G. Knepley         supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
3381b5da9499SMatthew G. Knepley       }
3382b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
3383b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
3384b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
3385b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
3386b5da9499SMatthew G. Knepley 
3387b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
3388b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
3389b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
3390b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
3391b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
339242525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
3393b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
3394b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
3395b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
339642525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
339742525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
3398b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);}
3399b5da9499SMatthew G. Knepley         }
3400b5da9499SMatthew G. Knepley       }
3401b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
3402b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
3403b5da9499SMatthew G. Knepley #if 1
3404b5da9499SMatthew 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);
3405b5da9499SMatthew G. Knepley       for (p = 0; p < 2+size*2+cellSize; ++p) {
3406b5da9499SMatthew 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);
3407b5da9499SMatthew G. Knepley       }
3408b5da9499SMatthew G. Knepley #endif
3409b5da9499SMatthew G. Knepley     }
3410b5da9499SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
3411b5da9499SMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
3412b5da9499SMatthew G. Knepley     break;
34139b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
34146ce3c06aSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
34156ce3c06aSMatthew G. Knepley     /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
34166ce3c06aSMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
34176ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
34186ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
34196ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
34206ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
34216ce3c06aSMatthew G. Knepley 
34226ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
34236ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
34246ce3c06aSMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
34256ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
34266ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
34276ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
34286ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
34296ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
34306ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
34316ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
34326ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
34336ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
34346ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
34356ce3c06aSMatthew G. Knepley #if 1
34366ce3c06aSMatthew 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);
34376ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
34386ce3c06aSMatthew 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);
34396ce3c06aSMatthew G. Knepley       }
34406ce3c06aSMatthew G. Knepley #endif
34416ce3c06aSMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
34426ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
34436ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
34446ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
34456ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
34466ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
34476ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
34486ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
34496ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
34506ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
34516ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
34526ce3c06aSMatthew G. Knepley #if 1
34536ce3c06aSMatthew 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);
34546ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
34556ce3c06aSMatthew 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);
34566ce3c06aSMatthew G. Knepley       }
34576ce3c06aSMatthew G. Knepley #endif
34586ce3c06aSMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
34596ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
34606ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
34616ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
34626ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
34636ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
34646ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
34656ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
34666ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
34676ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
34686ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
34696ce3c06aSMatthew G. Knepley #if 1
34706ce3c06aSMatthew 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);
34716ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
34726ce3c06aSMatthew 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);
34736ce3c06aSMatthew G. Knepley       }
34746ce3c06aSMatthew G. Knepley #endif
34756ce3c06aSMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
34766ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
34776ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
34786ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
34796ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
34806ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
34816ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
34826ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
34836ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
34846ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
34856ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
34866ce3c06aSMatthew G. Knepley #if 1
34876ce3c06aSMatthew 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);
34886ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
34896ce3c06aSMatthew 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);
34906ce3c06aSMatthew G. Knepley       }
34916ce3c06aSMatthew G. Knepley #endif
34926ce3c06aSMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
34936ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
34946ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
34959ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
3496e5337592SStefano Zampini       orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0);
34979ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
34989ddff745SMatthew G. Knepley       orntNew[2] = 0;
34999ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
35009ddff745SMatthew G. Knepley       orntNew[3] = 2;
35016ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
35026ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
35036ce3c06aSMatthew G. Knepley #if 1
35046ce3c06aSMatthew 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);
35056ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
35066ce3c06aSMatthew 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);
35076ce3c06aSMatthew G. Knepley       }
35086ce3c06aSMatthew G. Knepley #endif
35096ce3c06aSMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
35106ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
35116ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
35129ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
35139ddff745SMatthew G. Knepley       orntNew[1] = 1;
35149ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
35156ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
35169ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
3517e5337592SStefano Zampini       orntNew[3] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 0)+1) : GetTriMidEdge_Static(ornt[3], 0);
35186ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
35196ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
35206ce3c06aSMatthew G. Knepley #if 1
35216ce3c06aSMatthew 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);
35226ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
35236ce3c06aSMatthew 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);
35246ce3c06aSMatthew G. Knepley       }
35256ce3c06aSMatthew G. Knepley #endif
35266ce3c06aSMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
35276ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
35286ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
35299ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
3530e5337592SStefano Zampini       orntNew[1] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2);
35319ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
35329ddff745SMatthew G. Knepley       orntNew[2] = -3;
35339ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
35349ddff745SMatthew G. Knepley       orntNew[3] = -2;
35356ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
35366ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
35376ce3c06aSMatthew G. Knepley #if 1
35386ce3c06aSMatthew 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);
35396ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
35406ce3c06aSMatthew 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);
35416ce3c06aSMatthew G. Knepley       }
35426ce3c06aSMatthew G. Knepley #endif
35436ce3c06aSMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
35446ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
35456ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
35469ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
35476ce3c06aSMatthew G. Knepley       orntNew[1] = -3;
35489ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
3549e5337592SStefano Zampini       orntNew[2] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 0)+1) : GetTriMidEdge_Static(ornt[1], 0);
35509ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
35519ddff745SMatthew G. Knepley       orntNew[3] = -3;
35526ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
35536ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
35546ce3c06aSMatthew G. Knepley #if 1
35556ce3c06aSMatthew 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);
35566ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
35576ce3c06aSMatthew 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);
35586ce3c06aSMatthew G. Knepley       }
35596ce3c06aSMatthew G. Knepley #endif
35606ce3c06aSMatthew G. Knepley     }
35616ce3c06aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
35626ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
35636ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4;
3564d3a1cc75SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
35653b61eb6dSMatthew G. Knepley       PetscInt        coneNew[5], orntNew[5], o, of, i;
35666ce3c06aSMatthew G. Knepley 
35676ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
35686ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
3569d3a1cc75SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
3570084f9c62SMatthew G. Knepley       o = ornt[0] < 0 ? -1 : 1;
35716ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
35726ce3c06aSMatthew G. Knepley         coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r);
35736ce3c06aSMatthew G. Knepley         orntNew[0] = ornt[0];
35746ce3c06aSMatthew G. Knepley         coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r);
35756ce3c06aSMatthew G. Knepley         orntNew[1] = ornt[1];
3576084f9c62SMatthew G. Knepley         of = fornt[GetTriEdge_Static(ornt[0], r)]       < 0 ? -1 : 1;
35773b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], r)       + 2;
35783b61eb6dSMatthew 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);
35793b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
35803b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2;
35813b61eb6dSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r);
35823b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
35833b61eb6dSMatthew G. Knepley         of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1;
35843b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2;
35853b61eb6dSMatthew 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);
35863b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
35876ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
35886ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
35896ce3c06aSMatthew G. Knepley #if 1
35906ce3c06aSMatthew 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);
35916ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
35926ce3c06aSMatthew 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);
35936ce3c06aSMatthew G. Knepley         }
35946ce3c06aSMatthew G. Knepley         for (p = 2; p < 5; ++p) {
35956ce3c06aSMatthew 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);
35966ce3c06aSMatthew G. Knepley         }
35976ce3c06aSMatthew G. Knepley #endif
35986ce3c06aSMatthew G. Knepley       }
35996ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3;
36006ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
36016ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3;
36026ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
36033b61eb6dSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1;
36046ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
36053b61eb6dSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2;
36066ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
36073b61eb6dSMatthew G. Knepley       coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0;
36086ce3c06aSMatthew G. Knepley       orntNew[4] = 0;
36096ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
36106ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
36116ce3c06aSMatthew G. Knepley #if 1
36126ce3c06aSMatthew 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);
36136ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
36146ce3c06aSMatthew 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);
36156ce3c06aSMatthew G. Knepley       }
36166ce3c06aSMatthew G. Knepley       for (p = 2; p < 5; ++p) {
36176ce3c06aSMatthew 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);
36186ce3c06aSMatthew G. Knepley       }
36196ce3c06aSMatthew G. Knepley #endif
36206ce3c06aSMatthew G. Knepley     }
36216ce3c06aSMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
36226ce3c06aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
3623854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
36246ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
36256ce3c06aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
36266ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
36276ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
36286ce3c06aSMatthew G. Knepley 
36296ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
36306ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
36316ce3c06aSMatthew G. Knepley       /* A triangle */
36326ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
36336ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
36346ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
36356ce3c06aSMatthew G. Knepley       orntNew[1] = -2;
36366ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
36376ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
36386ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
36396ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
36406ce3c06aSMatthew G. Knepley #if 1
36416ce3c06aSMatthew 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);
36426ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
36436ce3c06aSMatthew 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);
36446ce3c06aSMatthew G. Knepley       }
36456ce3c06aSMatthew G. Knepley #endif
36466ce3c06aSMatthew G. Knepley       /* B triangle */
36476ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
36486ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
36496ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
36506ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
36516ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
36526ce3c06aSMatthew G. Knepley       orntNew[2] = -2;
36536ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
36546ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
36556ce3c06aSMatthew G. Knepley #if 1
36566ce3c06aSMatthew 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);
36576ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
36586ce3c06aSMatthew 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);
36596ce3c06aSMatthew G. Knepley       }
36606ce3c06aSMatthew G. Knepley #endif
36616ce3c06aSMatthew G. Knepley       /* C triangle */
36626ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
36636ce3c06aSMatthew G. Knepley       orntNew[0] = -2;
36646ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
36656ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
36666ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
36676ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
36686ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
36696ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
36706ce3c06aSMatthew G. Knepley #if 1
36716ce3c06aSMatthew 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);
36726ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
36736ce3c06aSMatthew 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);
36746ce3c06aSMatthew G. Knepley       }
36756ce3c06aSMatthew G. Knepley #endif
36766ce3c06aSMatthew G. Knepley       /* D triangle */
36776ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
36786ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
36796ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
36806ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
36816ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
36826ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
36836ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
36846ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
36856ce3c06aSMatthew G. Knepley #if 1
36866ce3c06aSMatthew 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);
36876ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
36886ce3c06aSMatthew 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);
36896ce3c06aSMatthew G. Knepley       }
36906ce3c06aSMatthew G. Knepley #endif
36916ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
36926ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
36936ce3c06aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
36946ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
36959ddff745SMatthew G. Knepley           PetscInt subf;
36966ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
36976ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
36986ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
36996ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
37006ce3c06aSMatthew G. Knepley             if (cone[c] == f) break;
37016ce3c06aSMatthew G. Knepley           }
37029ddff745SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
37036ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
37049ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
37056ce3c06aSMatthew G. Knepley           } else {
37069ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf);
37076ce3c06aSMatthew G. Knepley           }
37086ce3c06aSMatthew G. Knepley         }
37096ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
37106ce3c06aSMatthew G. Knepley #if 1
37119ddff745SMatthew 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);
37126ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
37136ce3c06aSMatthew 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);
37146ce3c06aSMatthew G. Knepley         }
37156ce3c06aSMatthew G. Knepley #endif
37166ce3c06aSMatthew G. Knepley       }
37176ce3c06aSMatthew G. Knepley     }
37186ce3c06aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
37196ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
37206ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8;
37216ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
37226ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
37236ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
37246ce3c06aSMatthew G. Knepley 
37256ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
37266ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
37276ce3c06aSMatthew G. Knepley       /* Face A: {c, a, d} */
3728e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
37296ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
3730e5337592SStefano Zampini       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
37316ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
3732e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2);
37336ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
37346ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37356ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
37366ce3c06aSMatthew G. Knepley #if 1
37376ce3c06aSMatthew 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);
37386ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
37396ce3c06aSMatthew 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);
37406ce3c06aSMatthew G. Knepley       }
37416ce3c06aSMatthew G. Knepley #endif
37426ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
37436ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
37446ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
37456ce3c06aSMatthew G. Knepley #if 1
37466ce3c06aSMatthew 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);
37476ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
37486ce3c06aSMatthew 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);
37496ce3c06aSMatthew G. Knepley       }
37506ce3c06aSMatthew G. Knepley #endif
37516ce3c06aSMatthew G. Knepley       ++newp;
37526ce3c06aSMatthew G. Knepley       /* Face B: {a, b, e} */
3753e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
37546ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
3755e5337592SStefano Zampini       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0);
37566ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
3757e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
37586ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
37596ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37606ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
37616ce3c06aSMatthew G. Knepley #if 1
37626ce3c06aSMatthew 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);
37636ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
37646ce3c06aSMatthew 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);
37656ce3c06aSMatthew G. Knepley       }
37666ce3c06aSMatthew G. Knepley #endif
37676ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
37686ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
37696ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
37706ce3c06aSMatthew G. Knepley #if 1
37716ce3c06aSMatthew 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);
37726ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
37736ce3c06aSMatthew 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);
37746ce3c06aSMatthew G. Knepley       }
37756ce3c06aSMatthew G. Knepley #endif
37766ce3c06aSMatthew G. Knepley       ++newp;
37776ce3c06aSMatthew G. Knepley       /* Face C: {c, f, b} */
3778e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
37796ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
3780e5337592SStefano Zampini       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
37816ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
3782e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1);
37836ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
37846ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37856ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
37866ce3c06aSMatthew G. Knepley #if 1
37876ce3c06aSMatthew 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);
37886ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
37896ce3c06aSMatthew 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);
37906ce3c06aSMatthew G. Knepley       }
37916ce3c06aSMatthew G. Knepley #endif
37926ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
37936ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
37946ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
37956ce3c06aSMatthew G. Knepley #if 1
37966ce3c06aSMatthew 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);
37976ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
37986ce3c06aSMatthew 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);
37996ce3c06aSMatthew G. Knepley       }
38006ce3c06aSMatthew G. Knepley #endif
38016ce3c06aSMatthew G. Knepley       ++newp;
38026ce3c06aSMatthew G. Knepley       /* Face D: {d, e, f} */
3803e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0);
38046ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
3805e5337592SStefano Zampini       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
38066ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
3807e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
38086ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
38096ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
38106ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
38116ce3c06aSMatthew G. Knepley #if 1
38126ce3c06aSMatthew 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);
38136ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
38146ce3c06aSMatthew 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);
38156ce3c06aSMatthew G. Knepley       }
38166ce3c06aSMatthew G. Knepley #endif
38176ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
38186ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
38196ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
38206ce3c06aSMatthew G. Knepley #if 1
38216ce3c06aSMatthew 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);
38226ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
38236ce3c06aSMatthew 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);
38246ce3c06aSMatthew G. Knepley       }
38256ce3c06aSMatthew G. Knepley #endif
38266ce3c06aSMatthew G. Knepley       ++newp;
38276ce3c06aSMatthew G. Knepley       /* Face E: {d, f, a} */
3828e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1);
38296ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
38306ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
38319ddff745SMatthew G. Knepley       orntNew[1] = -2;
3832e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2);
38336ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
38346ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
38356ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
38366ce3c06aSMatthew G. Knepley #if 1
38376ce3c06aSMatthew 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);
38386ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
38396ce3c06aSMatthew 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);
38406ce3c06aSMatthew G. Knepley       }
38416ce3c06aSMatthew G. Knepley #endif
38426ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
38436ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
38446ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
38456ce3c06aSMatthew G. Knepley #if 1
38466ce3c06aSMatthew 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);
38476ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
38486ce3c06aSMatthew 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);
38496ce3c06aSMatthew G. Knepley       }
38506ce3c06aSMatthew G. Knepley #endif
38516ce3c06aSMatthew G. Knepley       ++newp;
38526ce3c06aSMatthew G. Knepley       /* Face F: {c, a, f} */
3853e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2);
38546ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
38556ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
38569ddff745SMatthew G. Knepley       orntNew[1] = 0;
3857e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0);
38589ddff745SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
38596ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
38606ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
38616ce3c06aSMatthew G. Knepley #if 1
38626ce3c06aSMatthew 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);
38636ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
38646ce3c06aSMatthew 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);
38656ce3c06aSMatthew G. Knepley       }
38666ce3c06aSMatthew G. Knepley #endif
38676ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
38686ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
38696ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
38706ce3c06aSMatthew G. Knepley #if 1
38716ce3c06aSMatthew 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);
38726ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
38736ce3c06aSMatthew 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);
38746ce3c06aSMatthew G. Knepley       }
38756ce3c06aSMatthew G. Knepley #endif
38766ce3c06aSMatthew G. Knepley       ++newp;
38776ce3c06aSMatthew G. Knepley       /* Face G: {e, a, f} */
3878e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1);
38796ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
38806ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
38819ddff745SMatthew G. Knepley       orntNew[1] = 0;
3882e5337592SStefano Zampini       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1);
38836ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
38846ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
38856ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
38866ce3c06aSMatthew G. Knepley #if 1
38876ce3c06aSMatthew 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);
38886ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
38896ce3c06aSMatthew 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);
38906ce3c06aSMatthew G. Knepley       }
38916ce3c06aSMatthew G. Knepley #endif
38926ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
38936ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
38946ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
38956ce3c06aSMatthew G. Knepley #if 1
38966ce3c06aSMatthew 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);
38976ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
38986ce3c06aSMatthew 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);
38996ce3c06aSMatthew G. Knepley       }
39006ce3c06aSMatthew G. Knepley #endif
39016ce3c06aSMatthew G. Knepley       ++newp;
39026ce3c06aSMatthew G. Knepley       /* Face H: {a, b, f} */
3903e5337592SStefano Zampini       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0);
39046ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
3905e5337592SStefano Zampini       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2);
39066ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
39076ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
39089ddff745SMatthew G. Knepley       orntNew[2] = -2;
39096ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
39106ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
39116ce3c06aSMatthew G. Knepley #if 1
39126ce3c06aSMatthew 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);
39136ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
39146ce3c06aSMatthew 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);
39156ce3c06aSMatthew G. Knepley       }
39166ce3c06aSMatthew G. Knepley #endif
39176ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
39186ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
39196ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
39206ce3c06aSMatthew G. Knepley #if 1
39216ce3c06aSMatthew 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);
39226ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
39236ce3c06aSMatthew 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);
39246ce3c06aSMatthew G. Knepley       }
39256ce3c06aSMatthew G. Knepley #endif
39266ce3c06aSMatthew G. Knepley       ++newp;
39276ce3c06aSMatthew G. Knepley     }
39286ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
39296ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
39306ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
39316ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
39326ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
39336ce3c06aSMatthew G. Knepley 
39346ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
39356ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
39366ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
39376ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
39386ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
39396ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
39406ce3c06aSMatthew G. Knepley 
39416ce3c06aSMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
39426ce3c06aSMatthew G. Knepley         orntNew[0]   = ornt[0];
39436ce3c06aSMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
39446ce3c06aSMatthew G. Knepley         orntNew[1]   = ornt[1];
39456ce3c06aSMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax);
39466ce3c06aSMatthew G. Knepley         orntNew[2+r] = 0;
39476ce3c06aSMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd      - eMax) + (f - fMax);
39486ce3c06aSMatthew G. Knepley         orntNew[3-r] = 0;
39496ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
39506ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
39516ce3c06aSMatthew G. Knepley #if 1
39526ce3c06aSMatthew 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);
39536ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
39546ce3c06aSMatthew 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);
39556ce3c06aSMatthew G. Knepley         }
39566ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
39576ce3c06aSMatthew 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);
39586ce3c06aSMatthew G. Knepley         }
39596ce3c06aSMatthew G. Knepley #endif
39606ce3c06aSMatthew G. Knepley         for (s = 0; s < size; ++s) {
3961d3a1cc75SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
3962084f9c62SMatthew G. Knepley           PetscInt        o, of;
39636ce3c06aSMatthew G. Knepley 
39646ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
39656ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
3966084f9c62SMatthew G. Knepley           o = orntCell[0] < 0 ? -1 : 1;
39676ce3c06aSMatthew G. Knepley           for (c = 2; c < 5; ++c) if (coneCell[c] == f) break;
39686ce3c06aSMatthew 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]);
3969d3a1cc75SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
3970084f9c62SMatthew G. Knepley           of = fornt[c-2] < 0 ? -1 : 1;
3971084f9c62SMatthew 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;
39726ce3c06aSMatthew G. Knepley         }
39736ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
39746ce3c06aSMatthew G. Knepley #if 1
39756ce3c06aSMatthew 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);
39766ce3c06aSMatthew G. Knepley         for (p = 0; p < size; ++p) {
39776ce3c06aSMatthew 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);
39786ce3c06aSMatthew G. Knepley         }
39796ce3c06aSMatthew G. Knepley #endif
39806ce3c06aSMatthew G. Knepley       }
39816ce3c06aSMatthew G. Knepley     }
39826ce3c06aSMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
39836ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
39846ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3;
39856ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
39866ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
39876ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
39886ce3c06aSMatthew G. Knepley 
39896ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
39906ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
39916ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
3992b598a9d5SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3;
39936ce3c06aSMatthew G. Knepley         orntNew[0] = 0;
3994b598a9d5SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3;
39956ce3c06aSMatthew G. Knepley         orntNew[1] = 0;
3996b598a9d5SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax);
39976ce3c06aSMatthew G. Knepley         orntNew[2] = 0;
3998b598a9d5SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r]       - fMax);
39996ce3c06aSMatthew G. Knepley         orntNew[3] = 0;
40006ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
40016ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
40026ce3c06aSMatthew G. Knepley #if 1
40036ce3c06aSMatthew 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);
40046ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
40056ce3c06aSMatthew 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);
40066ce3c06aSMatthew G. Knepley         }
40076ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
40086ce3c06aSMatthew 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);
40096ce3c06aSMatthew G. Knepley         }
40106ce3c06aSMatthew G. Knepley #endif
40116ce3c06aSMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r);
40126ce3c06aSMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3;
40136ce3c06aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
40146ce3c06aSMatthew G. Knepley #if 1
40156ce3c06aSMatthew 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);
40166ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
40176ce3c06aSMatthew 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);
40186ce3c06aSMatthew G. Knepley         }
40196ce3c06aSMatthew G. Knepley #endif
40206ce3c06aSMatthew G. Knepley       }
40216ce3c06aSMatthew G. Knepley     }
40226ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
40236ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
40246ce3c06aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
40256ce3c06aSMatthew G. Knepley 
40266ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
40276ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
40286ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
40296ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
40306ce3c06aSMatthew G. Knepley 
40316ce3c06aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
40326ce3c06aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
40336ce3c06aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
40346ce3c06aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
40356ce3c06aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
40366ce3c06aSMatthew G. Knepley #if 1
40376ce3c06aSMatthew 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);
40386ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
40396ce3c06aSMatthew 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);
40406ce3c06aSMatthew G. Knepley         }
40416ce3c06aSMatthew G. Knepley #endif
40426ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
40436ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
40446ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
40456ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
40466ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
40476ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
40486ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == e) break;
40496ce3c06aSMatthew G. Knepley           if (support[s] < fMax) {
40506ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
40516ce3c06aSMatthew G. Knepley           } else {
40526ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
40536ce3c06aSMatthew G. Knepley           }
40546ce3c06aSMatthew G. Knepley         }
40556ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
40566ce3c06aSMatthew G. Knepley #if 1
40576ce3c06aSMatthew 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);
40586ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
40596ce3c06aSMatthew 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);
40606ce3c06aSMatthew G. Knepley         }
40616ce3c06aSMatthew G. Knepley #endif
40626ce3c06aSMatthew G. Knepley       }
40636ce3c06aSMatthew G. Knepley     }
40646ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
40656ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
40666ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
40676ce3c06aSMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
40686ce3c06aSMatthew G. Knepley 
40696ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
40706ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
40716ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
40726ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
40736ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
40746ce3c06aSMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
40756ce3c06aSMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
40766ce3c06aSMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
40776ce3c06aSMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
40786ce3c06aSMatthew G. Knepley 
40796ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
40806ce3c06aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
40816ce3c06aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
40826ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
40836ce3c06aSMatthew G. Knepley #if 1
40846ce3c06aSMatthew 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);
40856ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
40866ce3c06aSMatthew 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);
40876ce3c06aSMatthew G. Knepley         }
40886ce3c06aSMatthew G. Knepley #endif
40896ce3c06aSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
40906ce3c06aSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
40916ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
40926ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
40936ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
40946ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
40956ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
40966ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
40976ce3c06aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
4098e5337592SStefano Zampini             er = GetTriMidEdgeInverse_Static(ornt[c], r);
40996ce3c06aSMatthew G. Knepley             if (er == eint[c]) {
41006ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
41016ce3c06aSMatthew G. Knepley             } else {
41026ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
41036ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
41046ce3c06aSMatthew G. Knepley             }
41056ce3c06aSMatthew G. Knepley           } else {
4106b598a9d5SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3;
41076ce3c06aSMatthew G. Knepley           }
41086ce3c06aSMatthew G. Knepley         }
41096ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
41106ce3c06aSMatthew G. Knepley #if 1
41116ce3c06aSMatthew 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);
41126ce3c06aSMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
41136ce3c06aSMatthew 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);
41146ce3c06aSMatthew G. Knepley         }
41156ce3c06aSMatthew G. Knepley #endif
41166ce3c06aSMatthew G. Knepley       }
41176ce3c06aSMatthew G. Knepley     }
41186ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
41196ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
41206ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
41216ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
41226ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
41236ce3c06aSMatthew G. Knepley 
41246ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
41256ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
41266ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
41276ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
41286ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
41296ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
41306ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
41316ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
41326ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
41336ce3c06aSMatthew G. Knepley #if 1
41346ce3c06aSMatthew 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);
41356ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
41366ce3c06aSMatthew 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);
41376ce3c06aSMatthew G. Knepley       }
41386ce3c06aSMatthew G. Knepley #endif
41396ce3c06aSMatthew G. Knepley       supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
41406ce3c06aSMatthew G. Knepley       supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
41416ce3c06aSMatthew G. Knepley       supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
41426ce3c06aSMatthew G. Knepley       supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
41436ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
41446ce3c06aSMatthew G. Knepley #if 1
41456ce3c06aSMatthew 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);
41466ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
41476ce3c06aSMatthew 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);
41486ce3c06aSMatthew G. Knepley       }
41496ce3c06aSMatthew G. Knepley #endif
41506ce3c06aSMatthew G. Knepley     }
41516ce3c06aSMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
41526ce3c06aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
41536ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
41546ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
41556ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
41566ce3c06aSMatthew G. Knepley 
41576ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
41586ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
41596ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
41606ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
41616ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
41626ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
41636ce3c06aSMatthew G. Knepley #if 1
41646ce3c06aSMatthew 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);
41656ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
41666ce3c06aSMatthew 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);
41676ce3c06aSMatthew G. Knepley       }
41686ce3c06aSMatthew G. Knepley #endif
41696ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
41706ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
41716ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
41726ce3c06aSMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
41736ce3c06aSMatthew 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]);
41746ce3c06aSMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2;
41756ce3c06aSMatthew G. Knepley       }
41766ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
41776ce3c06aSMatthew G. Knepley #if 1
41786ce3c06aSMatthew 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);
41796ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
41806ce3c06aSMatthew 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);
41816ce3c06aSMatthew G. Knepley       }
41826ce3c06aSMatthew G. Knepley #endif
41836ce3c06aSMatthew G. Knepley     }
41846ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
41856ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
41866ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
4187623f4348SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
41886ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
41896ce3c06aSMatthew G. Knepley 
41906ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
41916ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
41926ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
41936ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
41946ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
41956ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
41966ce3c06aSMatthew G. Knepley #if 1
41976ce3c06aSMatthew 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);
41986ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
41996ce3c06aSMatthew 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);
42006ce3c06aSMatthew G. Knepley       }
42016ce3c06aSMatthew G. Knepley #endif
42026ce3c06aSMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0;
42036ce3c06aSMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1;
42046ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
42056ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
42066ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
4207623f4348SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
42086ce3c06aSMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
42096ce3c06aSMatthew 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]);
4210b598a9d5SMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2;
4211b598a9d5SMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3;
42126ce3c06aSMatthew G. Knepley       }
42136ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
42146ce3c06aSMatthew G. Knepley #if 1
42156ce3c06aSMatthew 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);
42166ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
42176ce3c06aSMatthew 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);
42186ce3c06aSMatthew G. Knepley       }
42196ce3c06aSMatthew G. Knepley #endif
42206ce3c06aSMatthew G. Knepley     }
42216ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
42226ce3c06aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
42236ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
42246ce3c06aSMatthew G. Knepley       const PetscInt *support, *cone;
42256ce3c06aSMatthew G. Knepley       PetscInt        size, s;
42266ce3c06aSMatthew G. Knepley 
42276ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
42286ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
42296ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
42306ce3c06aSMatthew G. Knepley         PetscInt r = 0;
42316ce3c06aSMatthew G. Knepley 
42326ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
42336ce3c06aSMatthew G. Knepley         if (cone[1] == v) r = 1;
42346ce3c06aSMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
42356ce3c06aSMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax);
42366ce3c06aSMatthew G. Knepley       }
42376ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
42386ce3c06aSMatthew G. Knepley #if 1
42396ce3c06aSMatthew 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);
42406ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
42416ce3c06aSMatthew 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);
42426ce3c06aSMatthew G. Knepley       }
42436ce3c06aSMatthew G. Knepley #endif
42446ce3c06aSMatthew G. Knepley     }
42456ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
42466ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
42476ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
42486ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support;
42496ce3c06aSMatthew G. Knepley       PetscInt       *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s;
42506ce3c06aSMatthew G. Knepley 
42516ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
42526ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
42536ce3c06aSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
42546ce3c06aSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
42556ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
42566ce3c06aSMatthew G. Knepley         PetscInt r = 0;
42576ce3c06aSMatthew G. Knepley 
42586ce3c06aSMatthew G. Knepley         if (support[s] < fMax) {
42596ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
42606ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
42616ce3c06aSMatthew G. Knepley           for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
42626ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
42636ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
42646ce3c06aSMatthew G. Knepley           faceSize += 2;
42656ce3c06aSMatthew G. Knepley         } else {
42666ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax);
42676ce3c06aSMatthew G. Knepley           ++faceSize;
42686ce3c06aSMatthew G. Knepley         }
42696ce3c06aSMatthew G. Knepley       }
42706ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
42716ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
42726ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
42736ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
42746ce3c06aSMatthew G. Knepley 
42756ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
42766ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
42776ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
42786ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
42796ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
42806ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
42816ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
42826ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
42836ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
42846ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
42856ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
42866ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);}
42876ce3c06aSMatthew G. Knepley         }
42886ce3c06aSMatthew G. Knepley       }
42896ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
42906ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
42916ce3c06aSMatthew G. Knepley #if 1
42926ce3c06aSMatthew 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);
42936ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+faceSize+cellSize; ++p) {
42946ce3c06aSMatthew 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);
42956ce3c06aSMatthew G. Knepley       }
42966ce3c06aSMatthew G. Knepley #endif
42976ce3c06aSMatthew G. Knepley     }
42986ce3c06aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
42996ce3c06aSMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
43006ce3c06aSMatthew G. Knepley     break;
4301e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_3D:
4302e5337592SStefano Zampini     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
4303e5337592SStefano Zampini     /* All cells have 6 faces */
4304e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
4305e5337592SStefano Zampini       const PetscInt  newp = cStartNew + (c - cStart)*4;
4306e5337592SStefano Zampini       const PetscInt *cone, *ornt;
4307e5337592SStefano Zampini       PetscInt        coneNew[6];
4308e5337592SStefano Zampini       PetscInt        orntNew[6];
4309e5337592SStefano Zampini 
4310e5337592SStefano Zampini       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
4311e5337592SStefano Zampini       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
4312e5337592SStefano Zampini       /* A hex */
4313e5337592SStefano Zampini       coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */
4314e5337592SStefano Zampini       orntNew[0] = ornt[0] < 0 ? -1 : 1;
4315e5337592SStefano Zampini       coneNew[1] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 3;               /* T */
4316e5337592SStefano Zampini       orntNew[1] = -4;
4317e5337592SStefano Zampini       coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */
4318e5337592SStefano Zampini       orntNew[2] = ornt[2] < 0 ? -1 : 1;
4319e5337592SStefano Zampini       coneNew[3] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 0;               /* K */
4320e5337592SStefano Zampini       orntNew[3] = -1;
4321e5337592SStefano Zampini       coneNew[4] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 2;               /* R */
4322e5337592SStefano Zampini       orntNew[4] = 0;
4323e5337592SStefano Zampini       coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */
4324e5337592SStefano Zampini       orntNew[5] = ornt[1] < 0 ? -1 : 1;
4325e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
4326e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
4327e5337592SStefano Zampini #if 1
4328e5337592SStefano 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);
4329e5337592SStefano Zampini       for (p = 0; p < 6; ++p) {
4330e5337592SStefano 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);
4331e5337592SStefano Zampini       }
4332e5337592SStefano Zampini #endif
4333e5337592SStefano Zampini       /* B hex */
4334e5337592SStefano Zampini       coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */
4335e5337592SStefano Zampini       orntNew[0] = ornt[0] < 0 ? -2 : 0;
4336e5337592SStefano Zampini       coneNew[1] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 4;               /* T */
4337e5337592SStefano Zampini       orntNew[1] = 0;
4338e5337592SStefano Zampini       coneNew[2] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 0;               /* F */
4339e5337592SStefano Zampini       orntNew[2] = 0;
4340e5337592SStefano Zampini       coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */
4341e5337592SStefano Zampini       orntNew[3] = ornt[3] < 0 ? -2 : 0;
4342e5337592SStefano Zampini       coneNew[4] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 1;               /* R */
4343e5337592SStefano Zampini       orntNew[4] = 0;
4344e5337592SStefano Zampini       coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */
4345e5337592SStefano Zampini       orntNew[5] = ornt[1] < 0 ? -4 : 2;
4346e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
4347e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
4348e5337592SStefano Zampini #if 1
4349e5337592SStefano Zampini       if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew);
4350e5337592SStefano Zampini       for (p = 0; p < 6; ++p) {
4351e5337592SStefano 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);
4352e5337592SStefano Zampini       }
4353e5337592SStefano Zampini #endif
4354e5337592SStefano Zampini       /* C hex */
4355e5337592SStefano Zampini       coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */
4356e5337592SStefano Zampini       orntNew[0] = ornt[0] < 0 ? -4 : 2;
4357e5337592SStefano Zampini       coneNew[1] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 5;               /* T */
4358e5337592SStefano Zampini       orntNew[1] = -4;
4359e5337592SStefano Zampini       coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */
4360e5337592SStefano Zampini       orntNew[2] = ornt[2] < 0 ? -2 : 0;
4361e5337592SStefano Zampini       coneNew[3] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 1;               /* K */
4362e5337592SStefano Zampini       orntNew[3] = -1;
4363e5337592SStefano Zampini       coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */
4364e5337592SStefano Zampini       orntNew[4] = ornt[3] < 0 ? -1 : 1;
4365e5337592SStefano Zampini       coneNew[5] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 2;               /* L */
4366e5337592SStefano Zampini       orntNew[5] = -4;
4367e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
4368e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
4369e5337592SStefano Zampini #if 1
4370e5337592SStefano 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);
4371e5337592SStefano Zampini       for (p = 0; p < 6; ++p) {
4372e5337592SStefano 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);
4373e5337592SStefano Zampini       }
4374e5337592SStefano Zampini #endif
4375e5337592SStefano Zampini       /* D hex */
4376e5337592SStefano Zampini       coneNew[0] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 3;               /* B */
4377e5337592SStefano Zampini       orntNew[0] = 0;
4378e5337592SStefano Zampini       coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */
4379e5337592SStefano Zampini       orntNew[1] = ornt[3] < 0 ? -1 : 1;
4380e5337592SStefano Zampini       coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */
4381e5337592SStefano Zampini       orntNew[2] = ornt[2] < 0 ? -4 : 2;
4382e5337592SStefano Zampini       coneNew[3] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 4;               /* K */
4383e5337592SStefano Zampini       orntNew[3] = -1;
4384e5337592SStefano Zampini       coneNew[4] = fStartNew + (fEnd    - fStart)*3 + (c - cStart)*6 + 5;               /* R */
4385e5337592SStefano Zampini       orntNew[4] = 0;
4386e5337592SStefano Zampini       coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */
4387e5337592SStefano Zampini       orntNew[5] = ornt[1] < 0 ? -2 : 0;
4388e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
4389e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
4390e5337592SStefano Zampini #if 1
4391e5337592SStefano 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);
4392e5337592SStefano Zampini       for (p = 0; p < 6; ++p) {
4393e5337592SStefano 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);
4394e5337592SStefano Zampini       }
4395e5337592SStefano Zampini #endif
4396e5337592SStefano Zampini     }
4397e5337592SStefano Zampini     /* Split faces have 4 edges and the same cells as the parent */
4398e5337592SStefano Zampini     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
4399e5337592SStefano Zampini     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
4400e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
4401e5337592SStefano Zampini       const PetscInt  newp = fStartNew + (f - fStart)*3;
4402e5337592SStefano Zampini       const PetscInt *cone, *ornt, *support;
4403e5337592SStefano Zampini       PetscInt        coneNew[4], orntNew[4], coneSize, supportSize, s;
4404e5337592SStefano Zampini 
4405e5337592SStefano Zampini       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
4406e5337592SStefano Zampini       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
4407e5337592SStefano Zampini       /* A quad */
4408e5337592SStefano Zampini       coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
4409e5337592SStefano Zampini       orntNew[0] = ornt[2];
4410e5337592SStefano Zampini       coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
4411e5337592SStefano Zampini       orntNew[1] = ornt[0];
4412e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
4413e5337592SStefano Zampini       orntNew[2] = 0;
4414e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
4415e5337592SStefano Zampini       orntNew[3] = -2;
4416e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
4417e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
4418e5337592SStefano Zampini #if 1
4419e5337592SStefano 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);
4420e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4421e5337592SStefano 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);
4422e5337592SStefano Zampini       }
4423e5337592SStefano Zampini #endif
4424e5337592SStefano Zampini       /* B quad */
4425e5337592SStefano Zampini       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
4426e5337592SStefano Zampini       orntNew[0] = ornt[0];
4427e5337592SStefano Zampini       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
4428e5337592SStefano Zampini       orntNew[1] = ornt[1];
4429e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
4430e5337592SStefano Zampini       orntNew[2] = 0;
4431e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
4432e5337592SStefano Zampini       orntNew[3] = -2;
4433e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
4434e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
4435e5337592SStefano Zampini #if 1
4436e5337592SStefano 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);
4437e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4438e5337592SStefano 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);
4439e5337592SStefano Zampini       }
4440e5337592SStefano Zampini #endif
4441e5337592SStefano Zampini       /* C quad */
4442e5337592SStefano Zampini       coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
4443e5337592SStefano Zampini       orntNew[0] = ornt[1];
4444e5337592SStefano Zampini       coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
4445e5337592SStefano Zampini       orntNew[1] = ornt[2];
4446e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
4447e5337592SStefano Zampini       orntNew[2] = 0;
4448e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
4449e5337592SStefano Zampini       orntNew[3] = -2;
4450e5337592SStefano Zampini       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
4451e5337592SStefano Zampini       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
4452e5337592SStefano Zampini #if 1
4453e5337592SStefano 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);
4454e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4455e5337592SStefano 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);
4456e5337592SStefano Zampini       }
4457e5337592SStefano Zampini #endif
4458e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
4459e5337592SStefano Zampini       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
4460e5337592SStefano Zampini       for (r = 0; r < 3; ++r) {
4461e5337592SStefano Zampini         for (s = 0; s < supportSize; ++s) {
4462e5337592SStefano Zampini           PetscInt subf;
4463e5337592SStefano Zampini           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
4464e5337592SStefano Zampini           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4465e5337592SStefano Zampini           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
4466e5337592SStefano Zampini           for (c = 0; c < coneSize; ++c) {
4467e5337592SStefano Zampini             if (cone[c] == f) break;
4468e5337592SStefano Zampini           }
4469e5337592SStefano Zampini           subf = GetTriSubfaceInverse_Static(ornt[c], r);
4470e5337592SStefano Zampini           supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf];
4471e5337592SStefano Zampini         }
4472e5337592SStefano Zampini         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
4473e5337592SStefano Zampini #if 1
4474e5337592SStefano 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);
4475e5337592SStefano Zampini         for (p = 0; p < supportSize; ++p) {
4476e5337592SStefano 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);
4477e5337592SStefano Zampini         }
4478e5337592SStefano Zampini #endif
4479e5337592SStefano Zampini       }
4480e5337592SStefano Zampini     }
4481e5337592SStefano Zampini     /* Interior faces have 4 edges and 2 cells */
4482e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
4483e5337592SStefano Zampini       PetscInt        newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6;
4484e5337592SStefano Zampini       const PetscInt *cone, *ornt;
4485e5337592SStefano Zampini       PetscInt        coneNew[4], orntNew[4];
4486e5337592SStefano Zampini       PetscInt        supportNew[2];
4487e5337592SStefano Zampini 
4488e5337592SStefano Zampini       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
4489e5337592SStefano Zampini       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
4490e5337592SStefano Zampini       /* Face {a, g, m, h} */
4491e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0);
4492e5337592SStefano Zampini       orntNew[0] = 0;
4493e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
4494e5337592SStefano Zampini       orntNew[1] = 0;
4495e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
4496e5337592SStefano Zampini       orntNew[2] = -2;
4497e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2);
4498e5337592SStefano Zampini       orntNew[3] = -2;
4499e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4500e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4501e5337592SStefano Zampini #if 1
4502e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4503e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4504e5337592SStefano 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);
4505e5337592SStefano Zampini       }
4506e5337592SStefano Zampini #endif
4507e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 0;
4508e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 1;
4509e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4510e5337592SStefano Zampini #if 1
4511e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4512e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4513e5337592SStefano 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);
4514e5337592SStefano Zampini       }
4515e5337592SStefano Zampini #endif
4516e5337592SStefano Zampini       ++newp;
4517e5337592SStefano Zampini       /* Face {g, b, l , m} */
4518e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1);
4519e5337592SStefano Zampini       orntNew[0] = -2;
4520e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0);
4521e5337592SStefano Zampini       orntNew[1] = 0;
4522e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
4523e5337592SStefano Zampini       orntNew[2] = 0;
4524e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
4525e5337592SStefano Zampini       orntNew[3] = -2;
4526e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4527e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4528e5337592SStefano Zampini #if 1
4529e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4530e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4531e5337592SStefano 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);
4532e5337592SStefano Zampini       }
4533e5337592SStefano Zampini #endif
4534e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 1;
4535e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 2;
4536e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4537e5337592SStefano Zampini #if 1
4538e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4539e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4540e5337592SStefano 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);
4541e5337592SStefano Zampini       }
4542e5337592SStefano Zampini #endif
4543e5337592SStefano Zampini       ++newp;
4544e5337592SStefano Zampini       /* Face {c, g, m, i} */
4545e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2);
4546e5337592SStefano Zampini       orntNew[0] = 0;
4547e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
4548e5337592SStefano Zampini       orntNew[1] = 0;
4549e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
4550e5337592SStefano Zampini       orntNew[2] = -2;
4551e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0);
4552e5337592SStefano Zampini       orntNew[3] = -2;
4553e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4554e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4555e5337592SStefano Zampini #if 1
4556e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4557e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4558e5337592SStefano 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);
4559e5337592SStefano Zampini       }
4560e5337592SStefano Zampini #endif
4561e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 0;
4562e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 2;
4563e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4564e5337592SStefano Zampini #if 1
4565e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4566e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4567e5337592SStefano 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);
4568e5337592SStefano Zampini       }
4569e5337592SStefano Zampini #endif
4570e5337592SStefano Zampini       ++newp;
4571e5337592SStefano Zampini       /* Face {d, h, m, i} */
4572e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0);
4573e5337592SStefano Zampini       orntNew[0] = 0;
4574e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
4575e5337592SStefano Zampini       orntNew[1] = 0;
4576e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
4577e5337592SStefano Zampini       orntNew[2] = -2;
4578e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2);
4579e5337592SStefano Zampini       orntNew[3] = -2;
4580e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4581e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4582e5337592SStefano Zampini #if 1
4583e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4584e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4585e5337592SStefano 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);
4586e5337592SStefano Zampini       }
4587e5337592SStefano Zampini #endif
4588e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 0;
4589e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 3;
4590e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4591e5337592SStefano Zampini #if 1
4592e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4593e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4594e5337592SStefano 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);
4595e5337592SStefano Zampini       }
4596e5337592SStefano Zampini #endif
4597e5337592SStefano Zampini       ++newp;
4598e5337592SStefano Zampini       /* Face {h, m, l, e} */
4599e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
4600e5337592SStefano Zampini       orntNew[0] = 0;
4601e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
4602e5337592SStefano Zampini       orntNew[1] = -2;
4603e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1);
4604e5337592SStefano Zampini       orntNew[2] = -2;
4605e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1);
4606e5337592SStefano Zampini       orntNew[3] = 0;
4607e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4608e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4609e5337592SStefano Zampini #if 1
4610e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4611e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4612e5337592SStefano 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);
4613e5337592SStefano Zampini       }
4614e5337592SStefano Zampini #endif
4615e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 1;
4616e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 3;
4617e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4618e5337592SStefano Zampini #if 1
4619e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4620e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4621e5337592SStefano 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);
4622e5337592SStefano Zampini       }
4623e5337592SStefano Zampini #endif
4624e5337592SStefano Zampini       ++newp;
4625e5337592SStefano Zampini       /* Face {i, m, l, f} */
4626e5337592SStefano Zampini       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
4627e5337592SStefano Zampini       orntNew[0] = 0;
4628e5337592SStefano Zampini       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
4629e5337592SStefano Zampini       orntNew[1] = -2;
4630e5337592SStefano Zampini       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2);
4631e5337592SStefano Zampini       orntNew[2] = -2;
4632e5337592SStefano Zampini       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1);
4633e5337592SStefano Zampini       orntNew[3] = 0;
4634e5337592SStefano Zampini       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4635e5337592SStefano Zampini       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4636e5337592SStefano Zampini #if 1
4637e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4638e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4639e5337592SStefano 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);
4640e5337592SStefano Zampini       }
4641e5337592SStefano Zampini #endif
4642e5337592SStefano Zampini       supportNew[0] = (c - cStart)*4 + 2;
4643e5337592SStefano Zampini       supportNew[1] = (c - cStart)*4 + 3;
4644e5337592SStefano Zampini       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4645e5337592SStefano Zampini #if 1
4646e5337592SStefano Zampini       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4647e5337592SStefano Zampini       for (p = 0; p < 2; ++p) {
4648e5337592SStefano 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);
4649e5337592SStefano Zampini       }
4650e5337592SStefano Zampini #endif
4651e5337592SStefano Zampini       ++newp;
4652e5337592SStefano Zampini     }
4653e5337592SStefano Zampini     /* Split Edges have 2 vertices and the same faces as the parent */
4654e5337592SStefano Zampini     for (e = eStart; e < eEnd; ++e) {
4655e5337592SStefano Zampini       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
4656e5337592SStefano Zampini 
4657e5337592SStefano Zampini       for (r = 0; r < 2; ++r) {
4658e5337592SStefano Zampini         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
4659e5337592SStefano Zampini         const PetscInt *cone, *ornt, *support;
4660e5337592SStefano Zampini         PetscInt        coneNew[2], coneSize, c, supportSize, s;
4661e5337592SStefano Zampini 
4662e5337592SStefano Zampini         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
4663e5337592SStefano Zampini         coneNew[0]       = vStartNew + (cone[0] - vStart);
4664e5337592SStefano Zampini         coneNew[1]       = vStartNew + (cone[1] - vStart);
4665e5337592SStefano Zampini         coneNew[(r+1)%2] = newv;
4666e5337592SStefano Zampini         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4667e5337592SStefano Zampini #if 1
4668e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4669e5337592SStefano Zampini         for (p = 0; p < 2; ++p) {
4670e5337592SStefano Zampini           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
4671e5337592SStefano Zampini         }
4672e5337592SStefano Zampini #endif
4673e5337592SStefano Zampini         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
4674e5337592SStefano Zampini         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
4675e5337592SStefano Zampini         for (s = 0; s < supportSize; ++s) {
4676e5337592SStefano Zampini           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
4677e5337592SStefano Zampini           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4678e5337592SStefano Zampini           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
4679e5337592SStefano Zampini           for (c = 0; c < coneSize; ++c) {
4680e5337592SStefano Zampini             if (cone[c] == e) break;
4681e5337592SStefano Zampini           }
4682e5337592SStefano Zampini           supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3;
4683e5337592SStefano Zampini         }
4684e5337592SStefano Zampini         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4685e5337592SStefano Zampini #if 1
4686e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4687e5337592SStefano Zampini         for (p = 0; p < supportSize; ++p) {
4688e5337592SStefano 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);
4689e5337592SStefano Zampini         }
4690e5337592SStefano Zampini #endif
4691e5337592SStefano Zampini       }
4692e5337592SStefano Zampini     }
4693e5337592SStefano Zampini     /* Face edges have 2 vertices and 2 + cell faces supports */
4694e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
4695e5337592SStefano Zampini       const PetscInt *cone, *ornt, *support;
4696e5337592SStefano Zampini       PetscInt        coneSize, supportSize, s;
4697e5337592SStefano Zampini 
4698e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
4699e5337592SStefano Zampini       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
4700e5337592SStefano Zampini       for (r = 0; r < 3; ++r) {
4701e5337592SStefano Zampini         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
4702e5337592SStefano Zampini         PetscInt        coneNew[2];
4703e5337592SStefano Zampini         PetscInt        fint[4][3] = { {0, 1, 2},
4704e5337592SStefano Zampini                                        {3, 4, 0},
4705e5337592SStefano Zampini                                        {2, 5, 3},
4706e5337592SStefano Zampini                                        {1, 4, 5} };
4707e5337592SStefano Zampini 
4708e5337592SStefano Zampini         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
4709e5337592SStefano Zampini         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
4710e5337592SStefano Zampini         coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart;
4711e5337592SStefano Zampini         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4712e5337592SStefano Zampini #if 1
4713e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4714e5337592SStefano Zampini         for (p = 0; p < 2; ++p) {
4715e5337592SStefano 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);
4716e5337592SStefano Zampini         }
4717e5337592SStefano Zampini #endif
4718e5337592SStefano Zampini         supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3;
4719e5337592SStefano Zampini         supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3;
4720e5337592SStefano Zampini         for (s = 0; s < supportSize; ++s) {
4721e5337592SStefano Zampini           PetscInt er;
4722e5337592SStefano Zampini           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
4723e5337592SStefano Zampini           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4724e5337592SStefano Zampini           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
4725e5337592SStefano Zampini           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
4726e5337592SStefano Zampini           er = GetTriInteriorEdgeInverse_Static(ornt[c], r);
4727e5337592SStefano Zampini           supportRef[2+s] = fStartNew + (fEnd - fStart)*3 + (support[s] - cStart)*6 + fint[c][er];
4728e5337592SStefano Zampini         }
4729e5337592SStefano Zampini         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4730e5337592SStefano Zampini #if 1
4731e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4732e5337592SStefano Zampini         for (p = 0; p < supportSize + 2; ++p) {
4733e5337592SStefano 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);
4734e5337592SStefano Zampini         }
4735e5337592SStefano Zampini #endif
4736e5337592SStefano Zampini       }
4737e5337592SStefano Zampini     }
4738e5337592SStefano Zampini     /* Interior cell edges have 2 vertices and 3 faces */
4739e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
4740e5337592SStefano Zampini       const PetscInt *cone;
4741e5337592SStefano Zampini       PetscInt       fint[4][3] = { {0,1,2},
4742e5337592SStefano Zampini                                     {0,3,4},
4743e5337592SStefano Zampini                                     {2,3,5},
4744e5337592SStefano Zampini                                     {1,4,5} } ;
4745e5337592SStefano Zampini 
4746e5337592SStefano Zampini       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
4747e5337592SStefano Zampini       for (r = 0; r < 4; r++) {
4748e5337592SStefano Zampini         PetscInt       coneNew[2], supportNew[3];
4749e5337592SStefano Zampini         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r;
4750e5337592SStefano Zampini 
4751e5337592SStefano Zampini         coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
4752e5337592SStefano Zampini         coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd -fStart) + c - cStart;
4753e5337592SStefano Zampini         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4754e5337592SStefano Zampini #if 1
4755e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4756e5337592SStefano Zampini         for (p = 0; p < 2; ++p) {
4757e5337592SStefano 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);
4758e5337592SStefano Zampini         }
4759e5337592SStefano Zampini #endif
4760e5337592SStefano Zampini         supportNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][0];
4761e5337592SStefano Zampini         supportNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][1];
4762e5337592SStefano Zampini         supportNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][2];
4763e5337592SStefano Zampini         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4764e5337592SStefano Zampini #if 1
4765e5337592SStefano Zampini         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
4766e5337592SStefano Zampini         for (p = 0; p < 3; ++p) {
4767e5337592SStefano 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);
4768e5337592SStefano Zampini         }
4769e5337592SStefano Zampini #endif
4770e5337592SStefano Zampini       }
4771e5337592SStefano Zampini     }
4772e5337592SStefano Zampini     /* Old vertices have identical supports */
4773e5337592SStefano Zampini     for (v = vStart; v < vEnd; ++v) {
4774e5337592SStefano Zampini       const PetscInt  newp = vStartNew + (v - vStart);
4775e5337592SStefano Zampini       const PetscInt *support, *cone;
4776e5337592SStefano Zampini       PetscInt        size, s;
4777e5337592SStefano Zampini 
4778e5337592SStefano Zampini       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
4779e5337592SStefano Zampini       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
4780e5337592SStefano Zampini       for (s = 0; s < size; ++s) {
4781e5337592SStefano Zampini         PetscInt r = 0;
4782e5337592SStefano Zampini 
4783e5337592SStefano Zampini         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4784e5337592SStefano Zampini         if (cone[1] == v) r = 1;
4785e5337592SStefano Zampini         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
4786e5337592SStefano Zampini       }
4787e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4788e5337592SStefano Zampini #if 1
4789e5337592SStefano Zampini       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
4790e5337592SStefano Zampini       for (p = 0; p < size; ++p) {
4791e5337592SStefano 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);
4792e5337592SStefano Zampini       }
4793e5337592SStefano Zampini #endif
4794e5337592SStefano Zampini     }
4795e5337592SStefano Zampini     /* Edge vertices have 2 + faces supports */
4796e5337592SStefano Zampini     for (e = eStart; e < eEnd; ++e) {
4797e5337592SStefano Zampini       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
4798e5337592SStefano Zampini       const PetscInt *cone, *support;
4799e5337592SStefano Zampini       PetscInt        size, s;
4800e5337592SStefano Zampini 
4801e5337592SStefano Zampini       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
4802e5337592SStefano Zampini       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
4803e5337592SStefano Zampini       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
4804e5337592SStefano Zampini       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
4805e5337592SStefano Zampini       for (s = 0; s < size; ++s) {
4806e5337592SStefano Zampini         PetscInt r = 0, coneSize;
4807e5337592SStefano Zampini 
4808e5337592SStefano Zampini         ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
4809e5337592SStefano Zampini         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4810e5337592SStefano Zampini         for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
4811e5337592SStefano Zampini         supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + r;
4812e5337592SStefano Zampini       }
4813e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4814e5337592SStefano Zampini #if 1
4815e5337592SStefano Zampini       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
4816e5337592SStefano Zampini       for (p = 0; p < 2+size; ++p) {
4817e5337592SStefano 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);
4818e5337592SStefano Zampini       }
4819e5337592SStefano Zampini #endif
4820e5337592SStefano Zampini     }
4821e5337592SStefano Zampini     /* Face vertices have 3 + cells supports */
4822e5337592SStefano Zampini     for (f = fStart; f < fEnd; ++f) {
4823e5337592SStefano Zampini       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
4824e5337592SStefano Zampini       const PetscInt *cone, *support;
4825e5337592SStefano Zampini       PetscInt        size, s;
4826e5337592SStefano Zampini 
4827e5337592SStefano Zampini       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
4828e5337592SStefano Zampini       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
4829e5337592SStefano Zampini       supportRef[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0;
4830e5337592SStefano Zampini       supportRef[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1;
4831e5337592SStefano Zampini       supportRef[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2;
4832e5337592SStefano Zampini       for (s = 0; s < size; ++s) {
4833e5337592SStefano Zampini         PetscInt r = 0, coneSize;
4834e5337592SStefano Zampini 
4835e5337592SStefano Zampini         ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
4836e5337592SStefano Zampini         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4837e5337592SStefano Zampini         for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;}
4838e5337592SStefano Zampini         supportRef[3+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (support[s] - cStart)*4 + r;
4839e5337592SStefano Zampini       }
4840e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4841e5337592SStefano Zampini #if 1
4842e5337592SStefano Zampini       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
4843e5337592SStefano Zampini       for (p = 0; p < 3+size; ++p) {
4844e5337592SStefano 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);
4845e5337592SStefano Zampini       }
4846e5337592SStefano Zampini #endif
4847e5337592SStefano Zampini     }
4848e5337592SStefano Zampini     /* Interior cell vertices have 4 supports */
4849e5337592SStefano Zampini     for (c = cStart; c < cEnd; ++c) {
4850e5337592SStefano Zampini       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + c - cStart;
4851e5337592SStefano Zampini       supportRef[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0;
4852e5337592SStefano Zampini       supportRef[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1;
4853e5337592SStefano Zampini       supportRef[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2;
4854e5337592SStefano Zampini       supportRef[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3;
4855e5337592SStefano Zampini       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4856e5337592SStefano Zampini #if 1
4857e5337592SStefano Zampini       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
4858e5337592SStefano Zampini       for (p = 0; p < 4; ++p) {
4859e5337592SStefano 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);
4860e5337592SStefano Zampini       }
4861e5337592SStefano Zampini #endif
4862e5337592SStefano Zampini     }
4863e5337592SStefano Zampini     ierr = PetscFree(supportRef);CHKERRQ(ierr);
4864e5337592SStefano Zampini     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
4865e5337592SStefano Zampini     break;
48669b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
48672eabf88fSMatthew G. Knepley     /*
48682eabf88fSMatthew G. Knepley      Bottom (viewed from top)    Top
48692eabf88fSMatthew G. Knepley      1---------2---------2       7---------2---------6
48702eabf88fSMatthew G. Knepley      |         |         |       |         |         |
48712eabf88fSMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
48722eabf88fSMatthew G. Knepley      |         |         |       |         |         |
48732eabf88fSMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
48742eabf88fSMatthew G. Knepley      |         |         |       |         |         |
48752eabf88fSMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
48762eabf88fSMatthew G. Knepley      |         |         |       |         |         |
48772eabf88fSMatthew G. Knepley      0---------0---------3       4---------0---------5
48782eabf88fSMatthew G. Knepley      */
48792eabf88fSMatthew G. Knepley     /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
48802eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
48812eabf88fSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
48822eabf88fSMatthew G. Knepley       const PetscInt *cone, *ornt;
48832eabf88fSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
48842eabf88fSMatthew G. Knepley 
48852eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
48862eabf88fSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
48872eabf88fSMatthew G. Knepley       /* A hex */
4888e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
48892eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
48902eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
48912eabf88fSMatthew G. Knepley       orntNew[1] = 0;
4892e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
48932eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
48942eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
48952eabf88fSMatthew G. Knepley       orntNew[3] = 0;
48962eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
48972eabf88fSMatthew G. Knepley       orntNew[4] = 0;
4898e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
48992eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
49002eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
49012eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
49022eabf88fSMatthew G. Knepley #if 1
49032eabf88fSMatthew 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);
49042eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
49052eabf88fSMatthew 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);
49062eabf88fSMatthew G. Knepley       }
49072eabf88fSMatthew G. Knepley #endif
49082eabf88fSMatthew G. Knepley       /* B hex */
4909e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
49102eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
49112eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
49122eabf88fSMatthew G. Knepley       orntNew[1] = 0;
49132eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
4914a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
4915e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
49162eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
49172eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
49182eabf88fSMatthew G. Knepley       orntNew[4] = 0;
4919e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
49202eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
49212eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
49222eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
49232eabf88fSMatthew G. Knepley #if 1
49242eabf88fSMatthew 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);
49252eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
49262eabf88fSMatthew 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);
49272eabf88fSMatthew G. Knepley       }
49282eabf88fSMatthew G. Knepley #endif
49292eabf88fSMatthew G. Knepley       /* C hex */
4930e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
49312eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
49322eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
49332eabf88fSMatthew G. Knepley       orntNew[1] = 0;
49342eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
4935a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
4936e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
49372eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
4938e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
49392eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
49402eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
4941a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
49422eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
49432eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
49442eabf88fSMatthew G. Knepley #if 1
49452eabf88fSMatthew 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);
49462eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
49472eabf88fSMatthew 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);
49482eabf88fSMatthew G. Knepley       }
49492eabf88fSMatthew G. Knepley #endif
49502eabf88fSMatthew G. Knepley       /* D hex */
4951e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
49522eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
49532eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
49542eabf88fSMatthew G. Knepley       orntNew[1] = 0;
4955e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
49562eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
49572eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
4958a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4959e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
49602eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
49612eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
4962a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
49632eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
49642eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
49652eabf88fSMatthew G. Knepley #if 1
49662eabf88fSMatthew 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);
49672eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
49682eabf88fSMatthew 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);
49692eabf88fSMatthew G. Knepley       }
49702eabf88fSMatthew G. Knepley #endif
49712eabf88fSMatthew G. Knepley       /* E hex */
49722eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
4973a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
4974e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
49752eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
4976e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
49772eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
49782eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
49792eabf88fSMatthew G. Knepley       orntNew[3] = 0;
49802eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
4981a3cddbf8SMatthew G. Knepley       orntNew[4] = -1;
4982e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
49832eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
4984b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
4985b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
49862eabf88fSMatthew G. Knepley #if 1
4987b164cbf2SMatthew 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);
49882eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
49892eabf88fSMatthew 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);
49902eabf88fSMatthew G. Knepley       }
49912eabf88fSMatthew G. Knepley #endif
49922eabf88fSMatthew G. Knepley       /* F hex */
49932eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
4994a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
4995e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
49962eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
4997e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
49982eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
49992eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
5000a3cddbf8SMatthew G. Knepley       orntNew[3] = -1;
5001e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
50022eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
50032eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
5004a3cddbf8SMatthew G. Knepley       orntNew[5] = 1;
5005b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
5006b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
50072eabf88fSMatthew G. Knepley #if 1
5008b164cbf2SMatthew 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);
50092eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
50102eabf88fSMatthew 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);
50112eabf88fSMatthew G. Knepley       }
50122eabf88fSMatthew G. Knepley #endif
50132eabf88fSMatthew G. Knepley       /* G hex */
50142eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
5015a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
5016e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
50172eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
50182eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
5019a3cddbf8SMatthew G. Knepley       orntNew[2] = 0;
5020e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
50212eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
5022e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
50232eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
50242eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
5025a3cddbf8SMatthew G. Knepley       orntNew[5] = -3;
5026b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
5027b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
50282eabf88fSMatthew G. Knepley #if 1
5029b164cbf2SMatthew 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);
50302eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
50312eabf88fSMatthew 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);
50322eabf88fSMatthew G. Knepley       }
50332eabf88fSMatthew G. Knepley #endif
50342eabf88fSMatthew G. Knepley       /* H hex */
50352eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
5036a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
5037e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
50382eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
50392eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
5040a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
5041e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
50422eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
50432eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
5044a3cddbf8SMatthew G. Knepley       orntNew[4] = 3;
5045e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
50462eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
5047b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
5048b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
50492eabf88fSMatthew G. Knepley #if 1
5050b164cbf2SMatthew 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);
50512eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
50522eabf88fSMatthew 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);
50532eabf88fSMatthew G. Knepley       }
50542eabf88fSMatthew G. Knepley #endif
50552eabf88fSMatthew G. Knepley     }
50562eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
50572eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
5058854ce69bSBarry Smith     ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
50592eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
50602eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
5061aaebbb9dSMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
50622eabf88fSMatthew 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};
50632eabf88fSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
50642eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
5065aaebbb9dSMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
50662eabf88fSMatthew G. Knepley 
50672eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
5068aaebbb9dSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
5069a3cddbf8SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
5070a3cddbf8SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
5071a3cddbf8SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
5072a3cddbf8SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
5073a3cddbf8SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
5074a3cddbf8SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
5075a3cddbf8SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4;
5076a3cddbf8SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
50772eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5078aaebbb9dSMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
50792eabf88fSMatthew G. Knepley #if 1
50802eabf88fSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
50812eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
50822eabf88fSMatthew 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);
50832eabf88fSMatthew G. Knepley         }
50842eabf88fSMatthew G. Knepley #endif
50852eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
50862eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
50872eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
50882eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
50892eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
50902eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
50912eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
50922eabf88fSMatthew G. Knepley             if (cone[c] == f) break;
50932eabf88fSMatthew G. Knepley           }
5094a3cddbf8SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)];
50952eabf88fSMatthew G. Knepley         }
50962eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
50972eabf88fSMatthew G. Knepley #if 1
50982eabf88fSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
50992eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
51002eabf88fSMatthew 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);
51012eabf88fSMatthew G. Knepley         }
51022eabf88fSMatthew G. Knepley #endif
51032eabf88fSMatthew G. Knepley       }
51042eabf88fSMatthew G. Knepley     }
51052eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
51062eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
51072eabf88fSMatthew 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};
5108afb2665bSMatthew G. Knepley       const PetscInt *cone, *ornt;
5109afb2665bSMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
51102eabf88fSMatthew G. Knepley 
51112eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
5112afb2665bSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
5113afb2665bSMatthew G. Knepley       /* A-D face */
5114afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0;
5115a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
5116a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
5117a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
5118afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5119a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
5120a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
5121a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
5122afb2665bSMatthew G. Knepley       orntNew[3] = -2;
51232eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5124afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
51252eabf88fSMatthew G. Knepley #if 1
51262eabf88fSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
51272eabf88fSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
51282eabf88fSMatthew 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);
51292eabf88fSMatthew G. Knepley       }
51302eabf88fSMatthew G. Knepley #endif
5131afb2665bSMatthew G. Knepley       /* C-D face */
5132afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1;
5133a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
5134a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
5135a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
5136afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5137a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
5138a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
5139a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
5140afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5141afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5142afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5143afb2665bSMatthew G. Knepley #if 1
5144afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5145afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5146afb2665bSMatthew 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);
5147afb2665bSMatthew G. Knepley       }
5148afb2665bSMatthew G. Knepley #endif
5149afb2665bSMatthew G. Knepley       /* B-C face */
5150afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2;
5151afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
5152afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5153afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
5154afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5155afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
5156afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5157afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
5158afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5159afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5160afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5161afb2665bSMatthew G. Knepley #if 1
5162afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5163afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5164afb2665bSMatthew 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);
5165afb2665bSMatthew G. Knepley       }
5166afb2665bSMatthew G. Knepley #endif
5167afb2665bSMatthew G. Knepley       /* A-B face */
5168afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3;
5169afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
5170afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5171afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
5172afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5173afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
5174afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5175afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
5176afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5177afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5178afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5179afb2665bSMatthew G. Knepley #if 1
5180afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5181afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5182afb2665bSMatthew 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);
5183afb2665bSMatthew G. Knepley       }
5184afb2665bSMatthew G. Knepley #endif
5185afb2665bSMatthew G. Knepley       /* E-F face */
5186afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4;
5187a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
5188afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5189a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
5190a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
5191a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
5192afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5193a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
5194a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
5195afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5196afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5197afb2665bSMatthew G. Knepley #if 1
5198afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5199afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5200afb2665bSMatthew 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);
5201afb2665bSMatthew G. Knepley       }
5202afb2665bSMatthew G. Knepley #endif
5203afb2665bSMatthew G. Knepley       /* F-G face */
5204afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5;
5205a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
5206afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5207a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
5208a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
5209a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
5210afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5211a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
5212a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
5213afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5214afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5215afb2665bSMatthew G. Knepley #if 1
5216afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5217afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5218afb2665bSMatthew 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);
5219afb2665bSMatthew G. Knepley       }
5220afb2665bSMatthew G. Knepley #endif
5221afb2665bSMatthew G. Knepley       /* G-H face */
5222afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6;
5223afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
5224afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5225afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
5226afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5227afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
5228afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5229afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
5230afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5231afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5232afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5233afb2665bSMatthew G. Knepley #if 1
5234afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5235afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5236afb2665bSMatthew 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);
5237afb2665bSMatthew G. Knepley       }
5238afb2665bSMatthew G. Knepley #endif
5239afb2665bSMatthew G. Knepley       /* E-H face */
5240afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7;
5241a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
5242afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5243a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
5244a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
5245a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
5246afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5247a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
5248a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
5249afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5250afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5251afb2665bSMatthew G. Knepley #if 1
5252afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5253afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5254afb2665bSMatthew 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);
5255afb2665bSMatthew G. Knepley       }
5256afb2665bSMatthew G. Knepley #endif
5257afb2665bSMatthew G. Knepley       /* A-E face */
5258afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8;
5259a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
5260a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
5261a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
5262afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5263a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
5264a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
5265a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
5266afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5267afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5268afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5269afb2665bSMatthew G. Knepley #if 1
5270afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5271afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5272afb2665bSMatthew 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);
5273afb2665bSMatthew G. Knepley       }
5274afb2665bSMatthew G. Knepley #endif
5275afb2665bSMatthew G. Knepley       /* D-F face */
5276afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9;
5277afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
5278afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5279afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
5280afb2665bSMatthew G. Knepley       orntNew[1] = 0;
5281afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
5282afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5283afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
5284afb2665bSMatthew G. Knepley       orntNew[3] = -2;
5285afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5286afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5287afb2665bSMatthew G. Knepley #if 1
5288afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5289afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5290afb2665bSMatthew 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);
5291afb2665bSMatthew G. Knepley       }
5292afb2665bSMatthew G. Knepley #endif
5293afb2665bSMatthew G. Knepley       /* C-G face */
5294afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10;
5295a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
5296afb2665bSMatthew G. Knepley       orntNew[0] = -2;
5297a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
5298a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
5299a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
5300afb2665bSMatthew G. Knepley       orntNew[2] = 0;
5301a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
5302a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
5303afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5304afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5305afb2665bSMatthew G. Knepley #if 1
5306afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5307afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5308afb2665bSMatthew 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);
5309afb2665bSMatthew G. Knepley       }
5310afb2665bSMatthew G. Knepley #endif
5311afb2665bSMatthew G. Knepley       /* B-H face */
5312afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11;
5313a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
5314a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
5315a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
5316a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
5317a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
5318a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
5319a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
5320a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
5321afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
5322afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
5323afb2665bSMatthew G. Knepley #if 1
5324afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
5325afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
5326afb2665bSMatthew 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);
5327afb2665bSMatthew G. Knepley       }
5328afb2665bSMatthew G. Knepley #endif
5329afb2665bSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
5330afb2665bSMatthew G. Knepley         newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
53312eabf88fSMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
53322eabf88fSMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
53332eabf88fSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
53342eabf88fSMatthew G. Knepley #if 1
53352eabf88fSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
53362eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
53372eabf88fSMatthew 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);
53382eabf88fSMatthew G. Knepley         }
53392eabf88fSMatthew G. Knepley #endif
53402eabf88fSMatthew G. Knepley       }
53412eabf88fSMatthew G. Knepley     }
53422eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
53432eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
53442eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
53452eabf88fSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
53462eabf88fSMatthew G. Knepley 
53472eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
53482eabf88fSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
53492eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
53502eabf88fSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
53512eabf88fSMatthew G. Knepley 
53522eabf88fSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
53532eabf88fSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
53542eabf88fSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
53552eabf88fSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
53562eabf88fSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
53572eabf88fSMatthew G. Knepley #if 1
53582eabf88fSMatthew 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);
53592eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
53602eabf88fSMatthew 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);
53612eabf88fSMatthew G. Knepley         }
53622eabf88fSMatthew G. Knepley #endif
53632eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
53642eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
53652eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
53662eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
53672eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
53682eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
53692eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
53702eabf88fSMatthew G. Knepley             if (cone[c] == e) break;
53712eabf88fSMatthew G. Knepley           }
53722eabf88fSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
53732eabf88fSMatthew G. Knepley         }
53742eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
53752eabf88fSMatthew G. Knepley #if 1
53762eabf88fSMatthew 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);
53772eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
53782eabf88fSMatthew 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);
53792eabf88fSMatthew G. Knepley         }
53802eabf88fSMatthew G. Knepley #endif
53812eabf88fSMatthew G. Knepley       }
53822eabf88fSMatthew G. Knepley     }
53832eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
53842eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
53856b852384SMatthew 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};
53862eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
53876b852384SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
53882eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
53892eabf88fSMatthew G. Knepley 
53902eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
53912eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
53922eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
53932eabf88fSMatthew G. Knepley 
53942eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
53952eabf88fSMatthew G. Knepley         coneNew[1] = newv;
53962eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
53972eabf88fSMatthew G. Knepley #if 1
53982eabf88fSMatthew 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);
53992eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
54002eabf88fSMatthew 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);
54012eabf88fSMatthew G. Knepley         }
54022eabf88fSMatthew G. Knepley #endif
54032eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
54042eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
54052eabf88fSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
54062eabf88fSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
54072eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
54086b852384SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
54096b852384SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
54106b852384SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
54112eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
5412a3cddbf8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
54132eabf88fSMatthew G. Knepley         }
54142eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
54152eabf88fSMatthew G. Knepley #if 1
54162eabf88fSMatthew 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);
54172eabf88fSMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
54182eabf88fSMatthew 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);
54192eabf88fSMatthew G. Knepley         }
54202eabf88fSMatthew G. Knepley #endif
54212eabf88fSMatthew G. Knepley       }
54222eabf88fSMatthew G. Knepley     }
54232eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
54242eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
54252eabf88fSMatthew 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};
54262eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
54272eabf88fSMatthew G. Knepley       const PetscInt *cone;
54282eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
54292eabf88fSMatthew G. Knepley 
54302eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
54312eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
54322eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
54332eabf88fSMatthew G. Knepley 
54342eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
54352eabf88fSMatthew G. Knepley         coneNew[1] = newv;
54362eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
54372eabf88fSMatthew G. Knepley #if 1
54382eabf88fSMatthew 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);
54392eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
54402eabf88fSMatthew 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);
54412eabf88fSMatthew G. Knepley         }
54422eabf88fSMatthew G. Knepley #endif
54432eabf88fSMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
54442eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
54452eabf88fSMatthew G. Knepley #if 1
54462eabf88fSMatthew 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);
54472eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
54482eabf88fSMatthew 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);
54492eabf88fSMatthew G. Knepley         }
54502eabf88fSMatthew G. Knepley #endif
54512eabf88fSMatthew G. Knepley       }
54522eabf88fSMatthew G. Knepley     }
54532eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
54542eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
54552eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
54562eabf88fSMatthew G. Knepley       const PetscInt *support, *cone;
54572eabf88fSMatthew G. Knepley       PetscInt        size, s;
54582eabf88fSMatthew G. Knepley 
54592eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
54602eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
54612eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
54622eabf88fSMatthew G. Knepley         PetscInt r = 0;
54632eabf88fSMatthew G. Knepley 
54642eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
54652eabf88fSMatthew G. Knepley         if (cone[1] == v) r = 1;
54662eabf88fSMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
54672eabf88fSMatthew G. Knepley       }
54682eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
54692eabf88fSMatthew G. Knepley #if 1
54702eabf88fSMatthew 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);
54712eabf88fSMatthew G. Knepley       for (p = 0; p < size; ++p) {
54722eabf88fSMatthew 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);
54732eabf88fSMatthew G. Knepley       }
54742eabf88fSMatthew G. Knepley #endif
54752eabf88fSMatthew G. Knepley     }
54762eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
54772eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
54782eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
54792eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
54802eabf88fSMatthew G. Knepley       PetscInt        size, s;
54812eabf88fSMatthew G. Knepley 
54822eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
54832eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
54842eabf88fSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
54852eabf88fSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
54862eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
54872eabf88fSMatthew G. Knepley         PetscInt r;
54882eabf88fSMatthew G. Knepley 
54892eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
5490a660e16cSMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
54912eabf88fSMatthew G. Knepley         supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r;
54922eabf88fSMatthew G. Knepley       }
54932eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
54942eabf88fSMatthew G. Knepley #if 1
54952eabf88fSMatthew 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);
54962eabf88fSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
54972eabf88fSMatthew 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);
54982eabf88fSMatthew G. Knepley       }
54992eabf88fSMatthew G. Knepley #endif
55002eabf88fSMatthew G. Knepley     }
55012eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
55022eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
55032eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
55042eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
55052eabf88fSMatthew G. Knepley       PetscInt        size, s;
55062eabf88fSMatthew G. Knepley 
55072eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
55082eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
55090793999aSMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 +  (f - fStart)*4 + r;
55102eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
55112eabf88fSMatthew G. Knepley         PetscInt r;
55122eabf88fSMatthew G. Knepley 
55132eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
55142eabf88fSMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
55152eabf88fSMatthew G. Knepley         supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r;
55162eabf88fSMatthew G. Knepley       }
55172eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
55182eabf88fSMatthew G. Knepley #if 1
55192eabf88fSMatthew 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);
55202eabf88fSMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
55212eabf88fSMatthew 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);
55222eabf88fSMatthew G. Knepley       }
55232eabf88fSMatthew G. Knepley #endif
55242eabf88fSMatthew G. Knepley     }
55252eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
55262eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
55272eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
55282eabf88fSMatthew G. Knepley       PetscInt       supportNew[6];
55292eabf88fSMatthew G. Knepley 
55302eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
55312eabf88fSMatthew G. Knepley         supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
55322eabf88fSMatthew G. Knepley       }
55332eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
55342eabf88fSMatthew G. Knepley     }
5535da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
55362eabf88fSMatthew G. Knepley     break;
55379b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
553827fcede3SMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
553927fcede3SMatthew G. Knepley     /*
554027fcede3SMatthew G. Knepley      Bottom (viewed from top)    Top
554127fcede3SMatthew G. Knepley      1---------2---------2       7---------2---------6
554227fcede3SMatthew G. Knepley      |         |         |       |         |         |
554327fcede3SMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
554427fcede3SMatthew G. Knepley      |         |         |       |         |         |
554527fcede3SMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
554627fcede3SMatthew G. Knepley      |         |         |       |         |         |
554727fcede3SMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
554827fcede3SMatthew G. Knepley      |         |         |       |         |         |
554927fcede3SMatthew G. Knepley      0---------0---------3       4---------0---------5
555027fcede3SMatthew G. Knepley      */
555127fcede3SMatthew G. Knepley     /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
555227fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
555327fcede3SMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
555427fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
555527fcede3SMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
555627fcede3SMatthew G. Knepley 
555727fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
555827fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
555927fcede3SMatthew G. Knepley       /* A hex */
556027fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
556127fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
556227fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
556327fcede3SMatthew G. Knepley       orntNew[1] = 0;
556427fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
556527fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
556627fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
556727fcede3SMatthew G. Knepley       orntNew[3] = 0;
556827fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
556927fcede3SMatthew G. Knepley       orntNew[4] = 0;
557027fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
557127fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
557227fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
557327fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
557427fcede3SMatthew G. Knepley #if 1
557527fcede3SMatthew 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);
557627fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
557727fcede3SMatthew 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);
557827fcede3SMatthew G. Knepley       }
557927fcede3SMatthew G. Knepley #endif
558027fcede3SMatthew G. Knepley       /* B hex */
558127fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
558227fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
558327fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
558427fcede3SMatthew G. Knepley       orntNew[1] = 0;
558527fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
558627fcede3SMatthew G. Knepley       orntNew[2] = -1;
558727fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
558827fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
558927fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
559027fcede3SMatthew G. Knepley       orntNew[4] = 0;
559127fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
559227fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
559327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
559427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
559527fcede3SMatthew G. Knepley #if 1
559627fcede3SMatthew 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);
559727fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
559827fcede3SMatthew 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);
559927fcede3SMatthew G. Knepley       }
560027fcede3SMatthew G. Knepley #endif
560127fcede3SMatthew G. Knepley       /* C hex */
560227fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
560327fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
560427fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
560527fcede3SMatthew G. Knepley       orntNew[1] = 0;
560627fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
560727fcede3SMatthew G. Knepley       orntNew[2] = -1;
560827fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
560927fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
561027fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
561127fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
561227fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
561327fcede3SMatthew G. Knepley       orntNew[5] = -4;
561427fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
561527fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
561627fcede3SMatthew G. Knepley #if 1
561727fcede3SMatthew 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);
561827fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
561927fcede3SMatthew 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);
562027fcede3SMatthew G. Knepley       }
562127fcede3SMatthew G. Knepley #endif
562227fcede3SMatthew G. Knepley       /* D hex */
562327fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
562427fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
562527fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
562627fcede3SMatthew G. Knepley       orntNew[1] = 0;
562727fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
562827fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
562927fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
563027fcede3SMatthew G. Knepley       orntNew[3] = 0;
563127fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
563227fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
563327fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
563427fcede3SMatthew G. Knepley       orntNew[5] = -4;
563527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
563627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
563727fcede3SMatthew G. Knepley #if 1
563827fcede3SMatthew 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);
563927fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
564027fcede3SMatthew 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);
564127fcede3SMatthew G. Knepley       }
564227fcede3SMatthew G. Knepley #endif
564327fcede3SMatthew G. Knepley       /* E hex */
564427fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
564527fcede3SMatthew G. Knepley       orntNew[0] = -4;
564627fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
564727fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
564827fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
564927fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
565027fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
565127fcede3SMatthew G. Knepley       orntNew[3] = 0;
565227fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
565327fcede3SMatthew G. Knepley       orntNew[4] = -1;
565427fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
565527fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
565627fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
565727fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
565827fcede3SMatthew G. Knepley #if 1
565927fcede3SMatthew 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);
566027fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
566127fcede3SMatthew 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);
566227fcede3SMatthew G. Knepley       }
566327fcede3SMatthew G. Knepley #endif
566427fcede3SMatthew G. Knepley       /* F hex */
566527fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
566627fcede3SMatthew G. Knepley       orntNew[0] = -4;
566727fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
566827fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
566927fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
567027fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
567127fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
567227fcede3SMatthew G. Knepley       orntNew[3] = -1;
567327fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
567427fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
567527fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
567627fcede3SMatthew G. Knepley       orntNew[5] = 1;
567727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
567827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
567927fcede3SMatthew G. Knepley #if 1
568027fcede3SMatthew 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);
568127fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
568227fcede3SMatthew 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);
568327fcede3SMatthew G. Knepley       }
568427fcede3SMatthew G. Knepley #endif
568527fcede3SMatthew G. Knepley       /* G hex */
568627fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
568727fcede3SMatthew G. Knepley       orntNew[0] = -4;
568827fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
568927fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
569027fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
569127fcede3SMatthew G. Knepley       orntNew[2] = 0;
569227fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
569327fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
569427fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
569527fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
569627fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
569727fcede3SMatthew G. Knepley       orntNew[5] = -3;
569827fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
569927fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
570027fcede3SMatthew G. Knepley #if 1
570127fcede3SMatthew 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);
570227fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
570327fcede3SMatthew 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);
570427fcede3SMatthew G. Knepley       }
570527fcede3SMatthew G. Knepley #endif
570627fcede3SMatthew G. Knepley       /* H hex */
570727fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
570827fcede3SMatthew G. Knepley       orntNew[0] = -4;
570927fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
571027fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
571127fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
571227fcede3SMatthew G. Knepley       orntNew[2] = -1;
571327fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
571427fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
571527fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
571627fcede3SMatthew G. Knepley       orntNew[4] = 3;
571727fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
571827fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
571927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
572027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
572127fcede3SMatthew G. Knepley #if 1
572227fcede3SMatthew 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);
572327fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
572427fcede3SMatthew 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);
572527fcede3SMatthew G. Knepley       }
572627fcede3SMatthew G. Knepley #endif
572727fcede3SMatthew G. Knepley     }
572827fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces: Front, Back, Sides */
572927fcede3SMatthew G. Knepley     /*
573027fcede3SMatthew G. Knepley      3---------2---------2
573127fcede3SMatthew G. Knepley      |         |         |
573227fcede3SMatthew G. Knepley      |    D    2    C    |
573327fcede3SMatthew G. Knepley      |         |         |
573427fcede3SMatthew G. Knepley      3----3----0----1----1
573527fcede3SMatthew G. Knepley      |         |         |
573627fcede3SMatthew G. Knepley      |    A    0    B    |
573727fcede3SMatthew G. Knepley      |         |         |
573827fcede3SMatthew G. Knepley      0---------0---------1
573927fcede3SMatthew G. Knepley      */
574027fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
574127fcede3SMatthew G. Knepley       const PetscInt  newp = (cMax - cStart)*8 + (c - cMax)*4;
574227fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
5743d273725eSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6], o, of, i;
574427fcede3SMatthew G. Knepley 
574527fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
574627fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
574727fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
5748d273725eSMatthew G. Knepley       o = ornt[0] < 0 ? -1 : 1;
574927fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
575027fcede3SMatthew G. Knepley         PetscInt subfA = GetQuadSubface_Static(ornt[0], r);
575127fcede3SMatthew G. Knepley         PetscInt edgeA = GetQuadEdge_Static(ornt[0], r);
5752d273725eSMatthew G. Knepley         PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4);
575327fcede3SMatthew 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]);
575427fcede3SMatthew G. Knepley         coneNew[0]         = fStartNew + (cone[0] - fStart)*4 + subfA;
575527fcede3SMatthew G. Knepley         orntNew[0]         = ornt[0];
575627fcede3SMatthew G. Knepley         coneNew[1]         = fStartNew + (cone[1] - fStart)*4 + subfA;
575727fcede3SMatthew G. Knepley         orntNew[1]         = ornt[0];
5758d273725eSMatthew G. Knepley         of = fornt[edgeA] < 0 ? -1 : 1;
5759d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], r) + 2;
5760d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0);
5761d273725eSMatthew G. Knepley         orntNew[i] = ornt[edgeA];
5762d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2;
5763d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeA;
5764d273725eSMatthew G. Knepley         orntNew[i] = 0;
5765d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2;
5766d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeB;
5767d273725eSMatthew G. Knepley         orntNew[i] = -2;
5768d273725eSMatthew G. Knepley         of = fornt[edgeB] < 0 ? -1 : 1;
5769d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2;
5770d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1);
5771d273725eSMatthew G. Knepley         orntNew[i] = ornt[edgeB];
577227fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
577327fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
577427fcede3SMatthew G. Knepley #if 1
577527fcede3SMatthew 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);
577627fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
577727fcede3SMatthew 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);
577827fcede3SMatthew G. Knepley         }
577927fcede3SMatthew G. Knepley         for (p = 2; p < 6; ++p) {
578027fcede3SMatthew 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);
578127fcede3SMatthew G. Knepley         }
578227fcede3SMatthew G. Knepley #endif
578327fcede3SMatthew G. Knepley       }
578427fcede3SMatthew G. Knepley     }
578527fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
578627fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
5787854ce69bSBarry Smith     ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
578827fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
578927fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
579027fcede3SMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
579127fcede3SMatthew 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};
579227fcede3SMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
579327fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
579427fcede3SMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
579527fcede3SMatthew G. Knepley 
579627fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
579727fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
579827fcede3SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
579927fcede3SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
580027fcede3SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
580127fcede3SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
580227fcede3SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
580327fcede3SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
580427fcede3SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4;
580527fcede3SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
580627fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
580727fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
580827fcede3SMatthew G. Knepley #if 1
580927fcede3SMatthew 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);
581027fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
581127fcede3SMatthew 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);
581227fcede3SMatthew G. Knepley         }
581327fcede3SMatthew G. Knepley #endif
581427fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
581527fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
581627fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
581727fcede3SMatthew G. Knepley           PetscInt subf;
581827fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
581927fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
582027fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
582127fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
582227fcede3SMatthew G. Knepley             if (cone[c] == f) break;
582327fcede3SMatthew G. Knepley           }
582427fcede3SMatthew G. Knepley           subf = GetQuadSubfaceInverse_Static(ornt[c], r);
582527fcede3SMatthew G. Knepley           if (support[s] < cMax) {
582627fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf];
582727fcede3SMatthew G. Knepley           } else {
582827fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax       - cStart)*8 + (support[s] - cMax)*4 + subf;
582927fcede3SMatthew G. Knepley           }
583027fcede3SMatthew G. Knepley         }
583127fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
583227fcede3SMatthew G. Knepley #if 1
583327fcede3SMatthew 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);
583427fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
583527fcede3SMatthew 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);
583627fcede3SMatthew G. Knepley         }
583727fcede3SMatthew G. Knepley #endif
583827fcede3SMatthew G. Knepley       }
583927fcede3SMatthew G. Knepley     }
5840d273725eSMatthew G. Knepley     /* Interior cell faces have 4 edges and 2 cells */
584127fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
584227fcede3SMatthew 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};
584327fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
584427fcede3SMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
584527fcede3SMatthew G. Knepley 
584627fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
584727fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
584827fcede3SMatthew G. Knepley       /* A-D face */
584927fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0;
585027fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
585127fcede3SMatthew G. Knepley       orntNew[0] = 0;
585227fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
585327fcede3SMatthew G. Knepley       orntNew[1] = 0;
585427fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
585527fcede3SMatthew G. Knepley       orntNew[2] = -2;
585627fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
585727fcede3SMatthew G. Knepley       orntNew[3] = -2;
585827fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
585927fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
586027fcede3SMatthew G. Knepley #if 1
586127fcede3SMatthew 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);
586227fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
586327fcede3SMatthew 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);
586427fcede3SMatthew G. Knepley       }
586527fcede3SMatthew G. Knepley #endif
586627fcede3SMatthew G. Knepley       /* C-D face */
586727fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1;
586827fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
586927fcede3SMatthew G. Knepley       orntNew[0] = 0;
587027fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
587127fcede3SMatthew G. Knepley       orntNew[1] = 0;
587227fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
587327fcede3SMatthew G. Knepley       orntNew[2] = -2;
587427fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
587527fcede3SMatthew G. Knepley       orntNew[3] = -2;
587627fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
587727fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
587827fcede3SMatthew G. Knepley #if 1
587927fcede3SMatthew 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);
588027fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
588127fcede3SMatthew 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);
588227fcede3SMatthew G. Knepley       }
588327fcede3SMatthew G. Knepley #endif
588427fcede3SMatthew G. Knepley       /* B-C face */
588527fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2;
588627fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
588727fcede3SMatthew G. Knepley       orntNew[0] = -2;
588827fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
588927fcede3SMatthew G. Knepley       orntNew[1] = 0;
589027fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
589127fcede3SMatthew G. Knepley       orntNew[2] = 0;
589227fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
589327fcede3SMatthew G. Knepley       orntNew[3] = -2;
589427fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
589527fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
589627fcede3SMatthew G. Knepley #if 1
589727fcede3SMatthew 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);
589827fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
589927fcede3SMatthew 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);
590027fcede3SMatthew G. Knepley       }
590127fcede3SMatthew G. Knepley #endif
590227fcede3SMatthew G. Knepley       /* A-B face */
590327fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3;
590427fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
590527fcede3SMatthew G. Knepley       orntNew[0] = -2;
590627fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
590727fcede3SMatthew G. Knepley       orntNew[1] = 0;
590827fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
590927fcede3SMatthew G. Knepley       orntNew[2] = 0;
591027fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
591127fcede3SMatthew G. Knepley       orntNew[3] = -2;
591227fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
591327fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
591427fcede3SMatthew G. Knepley #if 1
591527fcede3SMatthew 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);
591627fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
591727fcede3SMatthew 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);
591827fcede3SMatthew G. Knepley       }
591927fcede3SMatthew G. Knepley #endif
592027fcede3SMatthew G. Knepley       /* E-F face */
592127fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4;
592227fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
592327fcede3SMatthew G. Knepley       orntNew[0] = -2;
592427fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
592527fcede3SMatthew G. Knepley       orntNew[1] = -2;
592627fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
592727fcede3SMatthew G. Knepley       orntNew[2] = 0;
592827fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
592927fcede3SMatthew G. Knepley       orntNew[3] = 0;
593027fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
593127fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
593227fcede3SMatthew G. Knepley #if 1
593327fcede3SMatthew 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);
593427fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
593527fcede3SMatthew 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);
593627fcede3SMatthew G. Knepley       }
593727fcede3SMatthew G. Knepley #endif
593827fcede3SMatthew G. Knepley       /* F-G face */
593927fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5;
594027fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
594127fcede3SMatthew G. Knepley       orntNew[0] = -2;
594227fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
594327fcede3SMatthew G. Knepley       orntNew[1] = -2;
594427fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
594527fcede3SMatthew G. Knepley       orntNew[2] = 0;
594627fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
594727fcede3SMatthew G. Knepley       orntNew[3] = 0;
594827fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
594927fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
595027fcede3SMatthew G. Knepley #if 1
595127fcede3SMatthew 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);
595227fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
595327fcede3SMatthew 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);
595427fcede3SMatthew G. Knepley       }
595527fcede3SMatthew G. Knepley #endif
595627fcede3SMatthew G. Knepley       /* G-H face */
595727fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6;
595827fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
595927fcede3SMatthew G. Knepley       orntNew[0] = -2;
596027fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
596127fcede3SMatthew G. Knepley       orntNew[1] = 0;
596227fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
596327fcede3SMatthew G. Knepley       orntNew[2] = 0;
596427fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
596527fcede3SMatthew G. Knepley       orntNew[3] = -2;
596627fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
596727fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
596827fcede3SMatthew G. Knepley #if 1
596927fcede3SMatthew 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);
597027fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
597127fcede3SMatthew 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);
597227fcede3SMatthew G. Knepley       }
597327fcede3SMatthew G. Knepley #endif
597427fcede3SMatthew G. Knepley       /* E-H face */
597527fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7;
597627fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
597727fcede3SMatthew G. Knepley       orntNew[0] = -2;
597827fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
597927fcede3SMatthew G. Knepley       orntNew[1] = -2;
598027fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
598127fcede3SMatthew G. Knepley       orntNew[2] = 0;
598227fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
598327fcede3SMatthew G. Knepley       orntNew[3] = 0;
598427fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
598527fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
598627fcede3SMatthew G. Knepley #if 1
598727fcede3SMatthew 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);
598827fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
598927fcede3SMatthew 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);
599027fcede3SMatthew G. Knepley       }
599127fcede3SMatthew G. Knepley #endif
599227fcede3SMatthew G. Knepley       /* A-E face */
599327fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8;
599427fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
599527fcede3SMatthew G. Knepley       orntNew[0] = 0;
599627fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
599727fcede3SMatthew G. Knepley       orntNew[1] = 0;
599827fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
599927fcede3SMatthew G. Knepley       orntNew[2] = -2;
600027fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
600127fcede3SMatthew G. Knepley       orntNew[3] = -2;
600227fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
600327fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
600427fcede3SMatthew G. Knepley #if 1
600527fcede3SMatthew 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);
600627fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
600727fcede3SMatthew 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);
600827fcede3SMatthew G. Knepley       }
600927fcede3SMatthew G. Knepley #endif
601027fcede3SMatthew G. Knepley       /* D-F face */
601127fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9;
601227fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
601327fcede3SMatthew G. Knepley       orntNew[0] = -2;
601427fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
601527fcede3SMatthew G. Knepley       orntNew[1] = 0;
601627fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
601727fcede3SMatthew G. Knepley       orntNew[2] = 0;
601827fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
601927fcede3SMatthew G. Knepley       orntNew[3] = -2;
602027fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
602127fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
602227fcede3SMatthew G. Knepley #if 1
602327fcede3SMatthew 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);
602427fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
602527fcede3SMatthew 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);
602627fcede3SMatthew G. Knepley       }
602727fcede3SMatthew G. Knepley #endif
602827fcede3SMatthew G. Knepley       /* C-G face */
602927fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10;
603027fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
603127fcede3SMatthew G. Knepley       orntNew[0] = -2;
603227fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
603327fcede3SMatthew G. Knepley       orntNew[1] = -2;
603427fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
603527fcede3SMatthew G. Knepley       orntNew[2] = 0;
603627fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
603727fcede3SMatthew G. Knepley       orntNew[3] = 0;
603827fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
603927fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
604027fcede3SMatthew G. Knepley #if 1
604127fcede3SMatthew 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);
604227fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
604327fcede3SMatthew 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);
604427fcede3SMatthew G. Knepley       }
604527fcede3SMatthew G. Knepley #endif
604627fcede3SMatthew G. Knepley       /* B-H face */
604727fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11;
604827fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
604927fcede3SMatthew G. Knepley       orntNew[0] = 0;
605027fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
605127fcede3SMatthew G. Knepley       orntNew[1] = -2;
605227fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
605327fcede3SMatthew G. Knepley       orntNew[2] = -2;
605427fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
605527fcede3SMatthew G. Knepley       orntNew[3] = 0;
605627fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
605727fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
605827fcede3SMatthew G. Knepley #if 1
605927fcede3SMatthew 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);
606027fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
606127fcede3SMatthew 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);
606227fcede3SMatthew G. Knepley       }
606327fcede3SMatthew G. Knepley #endif
606427fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
606527fcede3SMatthew G. Knepley         newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
606627fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
606727fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
606827fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
606927fcede3SMatthew G. Knepley #if 1
607027fcede3SMatthew 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);
607127fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
607227fcede3SMatthew 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);
607327fcede3SMatthew G. Knepley         }
607427fcede3SMatthew G. Knepley #endif
607527fcede3SMatthew G. Knepley       }
607627fcede3SMatthew G. Knepley     }
607727fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
607827fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
607927fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
608027fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
608127fcede3SMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
608227fcede3SMatthew G. Knepley 
608327fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
608427fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
608527fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
608627fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
608727fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
608827fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
608927fcede3SMatthew G. Knepley 
609027fcede3SMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
609127fcede3SMatthew G. Knepley         orntNew[0]   = ornt[0];
609227fcede3SMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
609327fcede3SMatthew G. Knepley         orntNew[1]   = ornt[1];
609427fcede3SMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax);
609527fcede3SMatthew G. Knepley         orntNew[2+r] = 0;
609627fcede3SMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd      - eMax) + (f - fMax);
609727fcede3SMatthew G. Knepley         orntNew[3-r] = 0;
609827fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
609927fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
610027fcede3SMatthew G. Knepley #if 1
610127fcede3SMatthew 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);
610227fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
610327fcede3SMatthew 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);
610427fcede3SMatthew G. Knepley         }
610527fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
610627fcede3SMatthew 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);
610727fcede3SMatthew G. Knepley         }
610827fcede3SMatthew G. Knepley #endif
610927fcede3SMatthew G. Knepley         for (s = 0; s < size; ++s) {
611027fcede3SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
6111d273725eSMatthew G. Knepley           PetscInt        o, of;
611227fcede3SMatthew G. Knepley 
611327fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
611427fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
6115d273725eSMatthew G. Knepley           o = orntCell[0] < 0 ? -1 : 1;
611627fcede3SMatthew G. Knepley           for (c = 2; c < 6; ++c) if (coneCell[c] == f) break;
611727fcede3SMatthew 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]);
611827fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
6119d273725eSMatthew G. Knepley           of = fornt[c-2] < 0 ? -1 : 1;
6120d273725eSMatthew 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;
612127fcede3SMatthew G. Knepley         }
612227fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
612327fcede3SMatthew G. Knepley #if 1
612427fcede3SMatthew 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);
612527fcede3SMatthew G. Knepley         for (p = 0; p < size; ++p) {
612627fcede3SMatthew 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);
612727fcede3SMatthew G. Knepley         }
612827fcede3SMatthew G. Knepley #endif
612927fcede3SMatthew G. Knepley       }
613027fcede3SMatthew G. Knepley     }
613127fcede3SMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
613227fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
613327fcede3SMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4;
613427fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
613527fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
613627fcede3SMatthew G. Knepley       PetscInt        supportNew[2];
613727fcede3SMatthew G. Knepley 
613827fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
613927fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
614027fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
6141d273725eSMatthew G. Knepley #if 0
614227fcede3SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r);
614327fcede3SMatthew G. Knepley         orntNew[0] = 0;
614427fcede3SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r);
614527fcede3SMatthew G. Knepley         orntNew[1] = 0;
614627fcede3SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax);
614727fcede3SMatthew G. Knepley         orntNew[2] = 0;
614827fcede3SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd                                   - fMax) + (c - cMax);
614927fcede3SMatthew G. Knepley         orntNew[3] = 0;
6150d273725eSMatthew G. Knepley #else
6151d273725eSMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r;
6152d273725eSMatthew G. Knepley         orntNew[0] = 0;
6153d273725eSMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r;
6154d273725eSMatthew G. Knepley         orntNew[1] = 0;
6155d273725eSMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax);
6156d273725eSMatthew G. Knepley         orntNew[2] = 0;
6157d273725eSMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd      - fMax) + (c - cMax);
6158d273725eSMatthew G. Knepley         orntNew[3] = 0;
6159d273725eSMatthew G. Knepley #endif
616027fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
616127fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
616227fcede3SMatthew G. Knepley #if 1
616327fcede3SMatthew 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);
616427fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
616527fcede3SMatthew 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);
616627fcede3SMatthew G. Knepley         }
616727fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
616827fcede3SMatthew 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);
616927fcede3SMatthew G. Knepley         }
617027fcede3SMatthew G. Knepley #endif
617127fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r);
617227fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4);
617327fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
617427fcede3SMatthew G. Knepley #if 1
617527fcede3SMatthew 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);
617627fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
617727fcede3SMatthew 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);
617827fcede3SMatthew G. Knepley         }
617927fcede3SMatthew G. Knepley #endif
618027fcede3SMatthew G. Knepley       }
618127fcede3SMatthew G. Knepley     }
618227fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
618327fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
618427fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
618527fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
618627fcede3SMatthew G. Knepley 
618727fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
618827fcede3SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
618927fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
619027fcede3SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
619127fcede3SMatthew G. Knepley 
619227fcede3SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
619327fcede3SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
619427fcede3SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
619527fcede3SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
619627fcede3SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
619727fcede3SMatthew G. Knepley #if 1
619827fcede3SMatthew 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);
619927fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
620027fcede3SMatthew 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);
620127fcede3SMatthew G. Knepley         }
620227fcede3SMatthew G. Knepley #endif
620327fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
620427fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
620527fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
620627fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
620727fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
620827fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
620927fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
621027fcede3SMatthew G. Knepley             if (cone[c] == e) break;
621127fcede3SMatthew G. Knepley           }
621227fcede3SMatthew G. Knepley           if (support[s] < fMax) {
621327fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4;
621427fcede3SMatthew G. Knepley           } else {
621527fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
621627fcede3SMatthew G. Knepley           }
621727fcede3SMatthew G. Knepley         }
621827fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
621927fcede3SMatthew G. Knepley #if 1
622027fcede3SMatthew 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);
622127fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
622227fcede3SMatthew 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);
622327fcede3SMatthew G. Knepley         }
622427fcede3SMatthew G. Knepley #endif
622527fcede3SMatthew G. Knepley       }
622627fcede3SMatthew G. Knepley     }
622727fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
622827fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
622927fcede3SMatthew 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};
623027fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
623127fcede3SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
623227fcede3SMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
623327fcede3SMatthew G. Knepley 
623427fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
623527fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
623627fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
623727fcede3SMatthew G. Knepley 
623827fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
623927fcede3SMatthew G. Knepley         coneNew[1] = newv;
624027fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
624127fcede3SMatthew G. Knepley #if 1
624227fcede3SMatthew 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);
624327fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
624427fcede3SMatthew 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);
624527fcede3SMatthew G. Knepley         }
624627fcede3SMatthew G. Knepley #endif
624727fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
624827fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
624927fcede3SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
625027fcede3SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
625127fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
625227fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
625327fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
625427fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
625527fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
625627fcede3SMatthew G. Knepley           if (support[s] < cMax) {
625727fcede3SMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
625827fcede3SMatthew G. Knepley           } else {
6259d273725eSMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r;
626027fcede3SMatthew G. Knepley           }
626127fcede3SMatthew G. Knepley         }
626227fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
626327fcede3SMatthew G. Knepley #if 1
626427fcede3SMatthew 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);
626527fcede3SMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
626627fcede3SMatthew 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);
626727fcede3SMatthew G. Knepley         }
626827fcede3SMatthew G. Knepley #endif
626927fcede3SMatthew G. Knepley       }
627027fcede3SMatthew G. Knepley     }
627127fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
627227fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
627327fcede3SMatthew 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};
627427fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
627527fcede3SMatthew G. Knepley       const PetscInt *cone;
627627fcede3SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
627727fcede3SMatthew G. Knepley 
627827fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
627927fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
628027fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
628127fcede3SMatthew G. Knepley 
628227fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart);
628327fcede3SMatthew G. Knepley         coneNew[1] = newv;
628427fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
628527fcede3SMatthew G. Knepley #if 1
628627fcede3SMatthew 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);
628727fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
628827fcede3SMatthew 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);
628927fcede3SMatthew G. Knepley         }
629027fcede3SMatthew G. Knepley #endif
629127fcede3SMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
629227fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
629327fcede3SMatthew G. Knepley #if 1
629427fcede3SMatthew 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);
629527fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
629627fcede3SMatthew 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);
629727fcede3SMatthew G. Knepley         }
629827fcede3SMatthew G. Knepley #endif
629927fcede3SMatthew G. Knepley       }
630027fcede3SMatthew G. Knepley     }
630127fcede3SMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
630227fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
630327fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
630427fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
630527fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
630627fcede3SMatthew G. Knepley 
630727fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
630827fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
630927fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
631027fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
631127fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
631227fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
631327fcede3SMatthew G. Knepley #if 1
631427fcede3SMatthew 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);
631527fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
631627fcede3SMatthew 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);
631727fcede3SMatthew G. Knepley       }
631827fcede3SMatthew G. Knepley #endif
631927fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
632027fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
632127fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
632227fcede3SMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
632327fcede3SMatthew 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]);
632427fcede3SMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2;
632527fcede3SMatthew G. Knepley       }
632627fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
632727fcede3SMatthew G. Knepley #if 1
632827fcede3SMatthew 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);
632927fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
633027fcede3SMatthew 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);
633127fcede3SMatthew G. Knepley       }
633227fcede3SMatthew G. Knepley #endif
633327fcede3SMatthew G. Knepley     }
633427fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
633527fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
633627fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
633727fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
633827fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
633927fcede3SMatthew G. Knepley 
634027fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
634127fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
634227fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
634327fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
634427fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
634527fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
634627fcede3SMatthew G. Knepley #if 1
634727fcede3SMatthew 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);
634827fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
634927fcede3SMatthew 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);
635027fcede3SMatthew G. Knepley       }
635127fcede3SMatthew G. Knepley #endif
635227fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0;
635327fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1;
635427fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
635527fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
635627fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
635727fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
635827fcede3SMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
635927fcede3SMatthew 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]);
6360d273725eSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2;
636127fcede3SMatthew G. Knepley       }
636227fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
636327fcede3SMatthew G. Knepley #if 1
636427fcede3SMatthew 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);
636527fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
636627fcede3SMatthew 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);
636727fcede3SMatthew G. Knepley       }
636827fcede3SMatthew G. Knepley #endif
636927fcede3SMatthew G. Knepley     }
637027fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
637127fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
637227fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
637327fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
637427fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size;
637527fcede3SMatthew G. Knepley 
637627fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
637727fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr);
637827fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr);
637927fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart);
638027fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart);
638127fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
638227fcede3SMatthew G. Knepley #if 1
638327fcede3SMatthew 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);
638427fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
638527fcede3SMatthew 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);
638627fcede3SMatthew G. Knepley       }
638727fcede3SMatthew G. Knepley #endif
638827fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0;
638927fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1;
639027fcede3SMatthew G. Knepley       supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2;
639127fcede3SMatthew G. Knepley       supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3;
639227fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
639327fcede3SMatthew G. Knepley #if 1
639427fcede3SMatthew 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);
639527fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
639627fcede3SMatthew 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);
639727fcede3SMatthew G. Knepley       }
639827fcede3SMatthew G. Knepley #endif
639927fcede3SMatthew G. Knepley     }
640027fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
640127fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
640227fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
640327fcede3SMatthew G. Knepley       const PetscInt *support, *cone;
640427fcede3SMatthew G. Knepley       PetscInt        size, s;
640527fcede3SMatthew G. Knepley 
640627fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
640727fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
640827fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
640927fcede3SMatthew G. Knepley         PetscInt r = 0;
641027fcede3SMatthew G. Knepley 
641127fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
641227fcede3SMatthew G. Knepley         if (cone[1] == v) r = 1;
641327fcede3SMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
641427fcede3SMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax);
641527fcede3SMatthew G. Knepley       }
641627fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
641727fcede3SMatthew G. Knepley #if 1
641827fcede3SMatthew 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);
641927fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
642027fcede3SMatthew 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);
642127fcede3SMatthew G. Knepley       }
642227fcede3SMatthew G. Knepley #endif
642327fcede3SMatthew G. Knepley     }
642427fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
642527fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
642627fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
642727fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
642827fcede3SMatthew G. Knepley       PetscInt        size, s;
642927fcede3SMatthew G. Knepley 
643027fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
643127fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
643227fcede3SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
643327fcede3SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
643427fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
643527fcede3SMatthew G. Knepley         PetscInt r;
643627fcede3SMatthew G. Knepley 
643727fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
643827fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
643927fcede3SMatthew G. Knepley         if (support[s] < fMax) {
644027fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r;
644127fcede3SMatthew G. Knepley         } else {
644227fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax);
644327fcede3SMatthew G. Knepley         }
644427fcede3SMatthew G. Knepley       }
644527fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
644627fcede3SMatthew G. Knepley #if 1
644727fcede3SMatthew 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);
644827fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
644927fcede3SMatthew 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);
645027fcede3SMatthew G. Knepley       }
645127fcede3SMatthew G. Knepley #endif
645227fcede3SMatthew G. Knepley     }
645327fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
645427fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
645527fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
645627fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
645727fcede3SMatthew G. Knepley       PetscInt        size, s;
645827fcede3SMatthew G. Knepley 
645927fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
646027fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
646127fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 +  (f - fStart)*4 + r;
646227fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
646327fcede3SMatthew G. Knepley         PetscInt r;
646427fcede3SMatthew G. Knepley 
646527fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
646627fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
646727fcede3SMatthew G. Knepley         if (support[s] < cMax) {
646827fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r;
646927fcede3SMatthew G. Knepley         } else {
647027fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax       - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax);
647127fcede3SMatthew G. Knepley         }
647227fcede3SMatthew G. Knepley       }
647327fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
647427fcede3SMatthew G. Knepley #if 1
647527fcede3SMatthew 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);
647627fcede3SMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
647727fcede3SMatthew 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);
647827fcede3SMatthew G. Knepley       }
647927fcede3SMatthew G. Knepley #endif
648027fcede3SMatthew G. Knepley     }
648127fcede3SMatthew G. Knepley     /* Cell vertices have 6 supports */
648227fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
648327fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
648427fcede3SMatthew G. Knepley       PetscInt       supportNew[6];
648527fcede3SMatthew G. Knepley 
648627fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
648727fcede3SMatthew G. Knepley         supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
648827fcede3SMatthew G. Knepley       }
648927fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
649027fcede3SMatthew G. Knepley     }
649127fcede3SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
649227fcede3SMatthew G. Knepley     break;
649375d3a19aSMatthew G. Knepley   default:
649475d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
649575d3a19aSMatthew G. Knepley   }
649675d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
649775d3a19aSMatthew G. Knepley }
649875d3a19aSMatthew G. Knepley 
649986150812SJed Brown static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
650075d3a19aSMatthew G. Knepley {
650175d3a19aSMatthew G. Knepley   PetscSection          coordSection, coordSectionNew;
650275d3a19aSMatthew G. Knepley   Vec                   coordinates, coordinatesNew;
650375d3a19aSMatthew G. Knepley   PetscScalar          *coords, *coordsNew;
65043478d7aaSMatthew G. Knepley   const PetscInt        numVertices = depthSize ? depthSize[0] : 0;
650590b157c4SStefano Zampini   PetscInt              dim, spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax;
650690b157c4SStefano Zampini   PetscInt              c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f;
65079fc2a3f3SStefano Zampini   PetscInt              cStartNew, cEndNew, vEndNew, *parentId = NULL;
65088b9ced59SLisandro Dalcin   VecType               vtype;
65099fc2a3f3SStefano Zampini   PetscBool             isperiodic, localize = PETSC_FALSE, needcoords = PETSC_FALSE;
651090b157c4SStefano Zampini   const PetscReal      *maxCell, *L;
651190b157c4SStefano Zampini   const DMBoundaryType *bd;
651275d3a19aSMatthew G. Knepley   PetscErrorCode        ierr;
651375d3a19aSMatthew G. Knepley 
651475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
6515a57030b0SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
651675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
651775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
6518b5da9499SMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
651975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
652075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
652127fcede3SMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr);
652290b157c4SStefano Zampini   ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, NULL, NULL, &vStartNew);CHKERRQ(ierr);
652390b157c4SStefano Zampini   ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, NULL, NULL, &vEndNew);CHKERRQ(ierr);
652490b157c4SStefano Zampini   ierr = DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);CHKERRQ(ierr);
652590b157c4SStefano Zampini   /* Determine if we need to localize coordinates when generating them */
65269fc2a3f3SStefano Zampini   if (isperiodic && !maxCell) {
65279fc2a3f3SStefano Zampini     ierr = DMGetCoordinatesLocalized(dm, &localize);CHKERRQ(ierr);
65289fc2a3f3SStefano Zampini     if (!localize) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot refine if coordinates have not been localized");
65299fc2a3f3SStefano Zampini   }
6530b9ccc978SStefano Zampini   if (isperiodic) {
6531b9ccc978SStefano Zampini     ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)dm),((PetscObject)dm)->prefix,"DMPlex coords refinement options","DM");CHKERRQ(ierr);
6532b9ccc978SStefano Zampini     ierr = PetscOptionsBool("-dm_plex_refine_localize","Automatically localize from parent cells",NULL,localize,&localize,NULL);CHKERRQ(ierr);
6533b9ccc978SStefano Zampini     ierr = PetscOptionsEnd();CHKERRQ(ierr);
6534b9ccc978SStefano Zampini     if (localize) {
6535b9ccc978SStefano Zampini       ierr = DMLocalizeCoordinates(dm);CHKERRQ(ierr);
6536b9ccc978SStefano Zampini     }
6537b9ccc978SStefano Zampini   }
6538b9ccc978SStefano Zampini   ierr = DMSetPeriodicity(rdm, isperiodic,  maxCell,  L,  bd);CHKERRQ(ierr);
6539b9ccc978SStefano Zampini 
6540b9ccc978SStefano Zampini   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
6541b9ccc978SStefano Zampini   ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr);
6542b9ccc978SStefano Zampini   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr);
6543b9ccc978SStefano Zampini   ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr);
6544b9ccc978SStefano Zampini   ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr);
6545b9ccc978SStefano Zampini 
654690b157c4SStefano Zampini   if (localize) {
654790b157c4SStefano Zampini     PetscInt p, r, newp, *pi;
654890b157c4SStefano Zampini 
654990b157c4SStefano Zampini     /* New coordinates will be already localized on the cell */
655090b157c4SStefano Zampini     ierr = PetscSectionSetChart(coordSectionNew, 0, vStartNew+numVertices);CHKERRQ(ierr);
655190b157c4SStefano Zampini 
655290b157c4SStefano Zampini     /* We need the parentId to properly localize coordinates */
655390b157c4SStefano Zampini     ierr = PetscMalloc1(cEndNew-cStartNew,&pi);CHKERRQ(ierr);
655490b157c4SStefano Zampini     switch (refiner) {
655590b157c4SStefano Zampini     case REFINER_NOOP:
655690b157c4SStefano Zampini       break;
655790b157c4SStefano Zampini     case REFINER_SIMPLEX_1D:
655890b157c4SStefano Zampini       for (p = cStart; p < cEnd; ++p) {
655990b157c4SStefano Zampini         for (r = 0; r < 2; ++r) {
656090b157c4SStefano Zampini           newp     = (p - cStart)*2 + r;
656190b157c4SStefano Zampini           pi[newp] = p;
656290b157c4SStefano Zampini         }
656390b157c4SStefano Zampini       }
656490b157c4SStefano Zampini       break;
656590b157c4SStefano Zampini     case REFINER_SIMPLEX_2D:
656690b157c4SStefano Zampini       for (p = cStart; p < cEnd; ++p) {
656790b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
656890b157c4SStefano Zampini           newp     = (p - cStart)*4 + r;
656990b157c4SStefano Zampini           pi[newp] = p;
657090b157c4SStefano Zampini         }
657190b157c4SStefano Zampini       }
657290b157c4SStefano Zampini       break;
657390b157c4SStefano Zampini     case REFINER_HEX_2D:
657490b157c4SStefano Zampini       for (p = cStart; p < cEnd; ++p) {
657590b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
657690b157c4SStefano Zampini           newp     = (p - cStart)*4 + r;
657790b157c4SStefano Zampini           pi[newp] = p;
657890b157c4SStefano Zampini         }
657990b157c4SStefano Zampini       }
658090b157c4SStefano Zampini       break;
6581922a7158SLisandro Dalcin     case REFINER_SIMPLEX_TO_HEX_2D:
6582922a7158SLisandro Dalcin       for (p = cStart; p < cEnd; ++p) {
6583922a7158SLisandro Dalcin         for (r = 0; r < 3; ++r) {
6584922a7158SLisandro Dalcin           newp     = (p - cStart)*3 + r;
6585922a7158SLisandro Dalcin           pi[newp] = p;
6586922a7158SLisandro Dalcin         }
6587922a7158SLisandro Dalcin       }
6588922a7158SLisandro Dalcin       break;
658990b157c4SStefano Zampini     case REFINER_HYBRID_SIMPLEX_2D:
659090b157c4SStefano Zampini       for (p = cStart; p < cMax; ++p) {
659190b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
659290b157c4SStefano Zampini           newp     = (p - cStart)*4 + r;
659390b157c4SStefano Zampini           pi[newp] = p;
659490b157c4SStefano Zampini         }
659590b157c4SStefano Zampini       }
659690b157c4SStefano Zampini       for (p = cMax; p < cEnd; ++p) {
659790b157c4SStefano Zampini         for (r = 0; r < 2; ++r) {
659890b157c4SStefano Zampini           newp     = (cMax - cStart)*4 + (p - cMax)*2 + r;
659990b157c4SStefano Zampini           pi[newp] = p;
660090b157c4SStefano Zampini         }
660190b157c4SStefano Zampini       }
660290b157c4SStefano Zampini       break;
660390b157c4SStefano Zampini     case REFINER_HYBRID_HEX_2D:
660490b157c4SStefano Zampini       for (p = cStart; p < cMax; ++p) {
660590b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
660690b157c4SStefano Zampini           newp     = (p - cStart)*4 + r;
660790b157c4SStefano Zampini           pi[newp] = p;
660890b157c4SStefano Zampini         }
660990b157c4SStefano Zampini       }
661090b157c4SStefano Zampini       for (p = cMax; p < cEnd; ++p) {
661190b157c4SStefano Zampini         for (r = 0; r < 2; ++r) {
661290b157c4SStefano Zampini           newp     = (cMax - cStart)*4 + (p - cMax)*2 + r;
661390b157c4SStefano Zampini           pi[newp] = p;
661490b157c4SStefano Zampini         }
661590b157c4SStefano Zampini       }
661690b157c4SStefano Zampini       break;
661790b157c4SStefano Zampini     case REFINER_SIMPLEX_3D:
661890b157c4SStefano Zampini       for (p = cStart; p < cEnd; ++p) {
661990b157c4SStefano Zampini         for (r = 0; r < 8; ++r) {
662090b157c4SStefano Zampini           newp     = (p - cStart)*8 + r;
662190b157c4SStefano Zampini           pi[newp] = p;
662290b157c4SStefano Zampini         }
662390b157c4SStefano Zampini       }
662490b157c4SStefano Zampini       break;
662590b157c4SStefano Zampini     case REFINER_HYBRID_SIMPLEX_3D:
662690b157c4SStefano Zampini       for (p = cStart; p < cMax; ++p) {
662790b157c4SStefano Zampini         for (r = 0; r < 8; ++r) {
662890b157c4SStefano Zampini           newp     = (p - cStart)*8 + r;
662990b157c4SStefano Zampini           pi[newp] = p;
663090b157c4SStefano Zampini         }
663190b157c4SStefano Zampini       }
663290b157c4SStefano Zampini       for (p = cMax; p < cEnd; ++p) {
663390b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
663490b157c4SStefano Zampini           newp     = (cMax - cStart)*8 + (p - cMax)*4 + r;
663590b157c4SStefano Zampini           pi[newp] = p;
663690b157c4SStefano Zampini         }
663790b157c4SStefano Zampini       }
663890b157c4SStefano Zampini       break;
6639922a7158SLisandro Dalcin     case REFINER_SIMPLEX_TO_HEX_3D:
6640922a7158SLisandro Dalcin       for (p = cStart; p < cEnd; ++p) {
6641922a7158SLisandro Dalcin         for (r = 0; r < 4; ++r) {
6642922a7158SLisandro Dalcin           newp     = (p - cStart)*4 + r;
6643922a7158SLisandro Dalcin           pi[newp] = p;
6644922a7158SLisandro Dalcin         }
6645922a7158SLisandro Dalcin       }
6646922a7158SLisandro Dalcin       break;
664790b157c4SStefano Zampini     case REFINER_HEX_3D:
664890b157c4SStefano Zampini       for (p = cStart; p < cEnd; ++p) {
664990b157c4SStefano Zampini         for (r = 0; r < 8; ++r) {
665090b157c4SStefano Zampini           newp = (p - cStart)*8 + r;
665190b157c4SStefano Zampini           pi[newp] = p;
665290b157c4SStefano Zampini         }
665390b157c4SStefano Zampini       }
665490b157c4SStefano Zampini       break;
665590b157c4SStefano Zampini     case REFINER_HYBRID_HEX_3D:
665690b157c4SStefano Zampini       for (p = cStart; p < cMax; ++p) {
665790b157c4SStefano Zampini         for (r = 0; r < 8; ++r) {
665890b157c4SStefano Zampini           newp = (p - cStart)*8 + r;
665990b157c4SStefano Zampini           pi[newp] = p;
666090b157c4SStefano Zampini         }
666190b157c4SStefano Zampini       }
666290b157c4SStefano Zampini       for (p = cMax; p < cEnd; ++p) {
666390b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
666490b157c4SStefano Zampini           newp = (cMax - cStart)*8 + (p - cMax)*4 + r;
6665451a39c7SStefano Zampini           pi[newp] = p;
666690b157c4SStefano Zampini         }
666790b157c4SStefano Zampini       }
666890b157c4SStefano Zampini       break;
666990b157c4SStefano Zampini     default:
667090b157c4SStefano Zampini       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
667190b157c4SStefano Zampini     }
667290b157c4SStefano Zampini     parentId = pi;
667390b157c4SStefano Zampini   } else {
66743478d7aaSMatthew G. Knepley     ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr);
667590b157c4SStefano Zampini   }
667627fcede3SMatthew G. Knepley   if (cMax < 0) cMax = cEnd;
667775d3a19aSMatthew G. Knepley   if (fMax < 0) fMax = fEnd;
6678b5da9499SMatthew G. Knepley   if (eMax < 0) eMax = eEnd;
667990b157c4SStefano Zampini 
6680f1d7821bSLawrence Mitchell   /* All vertices have the spaceDim coordinates */
668190b157c4SStefano Zampini   if (localize) {
66829fc2a3f3SStefano Zampini     PetscInt c;
668390b157c4SStefano Zampini 
66849fc2a3f3SStefano Zampini     for (c = cStartNew; c < cEndNew; ++c) {
66859fc2a3f3SStefano Zampini       PetscInt *cone = NULL;
66869fc2a3f3SStefano Zampini       PetscInt  closureSize, coneSize = 0, p, pdof;
66879fc2a3f3SStefano Zampini 
66889fc2a3f3SStefano Zampini       ierr = PetscSectionGetDof(coordSection, parentId[c], &pdof); CHKERRQ(ierr);
66899fc2a3f3SStefano Zampini       if (pdof) { /* localize on all cells that are refinement of a localized parent cell */
66909fc2a3f3SStefano Zampini         ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
669190b157c4SStefano Zampini         for (p = 0; p < closureSize*2; p += 2) {
669290b157c4SStefano Zampini           const PetscInt point = cone[p];
669390b157c4SStefano Zampini           if ((point >= vStartNew) && (point < vEndNew)) coneSize++;
669490b157c4SStefano Zampini         }
66959fc2a3f3SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
66969fc2a3f3SStefano Zampini         ierr = PetscSectionSetDof(coordSectionNew, c, coneSize*spaceDim);CHKERRQ(ierr);
66979fc2a3f3SStefano Zampini         ierr = PetscSectionSetFieldDof(coordSectionNew, c, 0, coneSize*spaceDim);CHKERRQ(ierr);
66989fc2a3f3SStefano Zampini       }
669990b157c4SStefano Zampini     }
670090b157c4SStefano Zampini   }
67013478d7aaSMatthew G. Knepley   for (v = vStartNew; v < vStartNew+numVertices; ++v) {
6702f1d7821bSLawrence Mitchell     ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr);
6703f1d7821bSLawrence Mitchell     ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr);
670475d3a19aSMatthew G. Knepley   }
670575d3a19aSMatthew G. Knepley   ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr);
670646e270d4SMatthew G. Knepley   ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr);
670775d3a19aSMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
670875d3a19aSMatthew G. Knepley   ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr);
67098b9ced59SLisandro Dalcin   ierr = VecCreate(PETSC_COMM_SELF, &coordinatesNew);CHKERRQ(ierr);
671075d3a19aSMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr);
671175d3a19aSMatthew G. Knepley   ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr);
671260b9e8a1SMatthew G. Knepley   ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr);
671360b9e8a1SMatthew G. Knepley   ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr);
67148b9ced59SLisandro Dalcin   ierr = VecGetType(coordinates, &vtype);CHKERRQ(ierr);
67158b9ced59SLisandro Dalcin   ierr = VecSetType(coordinatesNew, vtype);CHKERRQ(ierr);
671675d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr);
671775d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
67189fc2a3f3SStefano Zampini 
6719b5da9499SMatthew G. Knepley   switch (refiner) {
67209b1a0e7fSLawrence Mitchell   case REFINER_NOOP: break;
6721e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_3D:
67229b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
67239b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
6724b5da9499SMatthew G. Knepley     /* Face vertices have the average of corner coordinates */
6725d856d60fSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
672627fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
6727b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
6728b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
6729b5da9499SMatthew G. Knepley 
6730b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
6731b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
6732b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
6733b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
6734b5da9499SMatthew G. Knepley       }
673590b157c4SStefano Zampini       if (localize) {
673690b157c4SStefano Zampini         const PetscInt *support = NULL;
673790b157c4SStefano Zampini         PetscInt       *rStar = NULL;
673890b157c4SStefano Zampini         PetscInt        supportSize, rStarSize, coff, s, ccoff[8];
673990b157c4SStefano Zampini         PetscBool       cellfound = PETSC_FALSE;
674090b157c4SStefano Zampini 
674190b157c4SStefano Zampini         ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
674290b157c4SStefano Zampini         ierr = DMPlexGetSupportSize(dm,f,&supportSize);CHKERRQ(ierr);
674390b157c4SStefano Zampini         ierr = DMPlexGetSupport(dm,f,&support);CHKERRQ(ierr);
674490b157c4SStefano Zampini         /* Compute average of coordinates for each cell sharing the face */
674590b157c4SStefano Zampini         for (s = 0; s < supportSize; ++s) {
674690b157c4SStefano Zampini           PetscScalar     coordsNewAux[3] = { 0.0, 0.0, 0.0 };
674790b157c4SStefano Zampini           PetscInt       *cellCone = NULL;
67489fc2a3f3SStefano Zampini           PetscInt        cellClosureSize, cellConeSize = 0, cdof;
674990b157c4SStefano Zampini           const PetscInt  cell = support[s];
675090b157c4SStefano Zampini           PetscBool       copyoff = PETSC_FALSE;
675190b157c4SStefano Zampini 
675290b157c4SStefano Zampini           ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr);
675390b157c4SStefano Zampini           for (p = 0; p < cellClosureSize*2; p += 2) {
675490b157c4SStefano Zampini             const PetscInt point = cellCone[p];
675590b157c4SStefano Zampini             if ((point >= vStart) && (point < vEnd)) cellCone[cellConeSize++] = point;
675690b157c4SStefano Zampini           }
67579fc2a3f3SStefano Zampini           ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr);
67589fc2a3f3SStefano Zampini           if (!cdof) { /* the parent cell does not have localized coordinates */
67599fc2a3f3SStefano Zampini             cellfound = PETSC_TRUE;
67609fc2a3f3SStefano Zampini             for (v = 0; v < coneSize; ++v) {
67619fc2a3f3SStefano Zampini               ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
67629fc2a3f3SStefano Zampini               for (d = 0; d < spaceDim; ++d) coordsNewAux[d] += coords[off[v]+d];
67639fc2a3f3SStefano Zampini             }
67649fc2a3f3SStefano Zampini             for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize;
67659fc2a3f3SStefano Zampini           } else {
67669fc2a3f3SStefano Zampini             ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr);
676790b157c4SStefano Zampini             for (p = 0; p < coneSize; ++p) {
676890b157c4SStefano Zampini               const PetscInt tv = cone[p];
676990b157c4SStefano Zampini               PetscInt       cv, voff;
677090b157c4SStefano Zampini               PetscBool      locv = PETSC_TRUE;
677190b157c4SStefano Zampini 
677290b157c4SStefano Zampini               for (cv = 0; cv < cellConeSize; ++cv) {
677390b157c4SStefano Zampini                 if (cellCone[cv] == tv) {
677490b157c4SStefano Zampini                   ccoff[p] = spaceDim*cv + coff;
677590b157c4SStefano Zampini                   break;
677690b157c4SStefano Zampini                 }
677790b157c4SStefano Zampini               }
677890b157c4SStefano Zampini               if (cv == cellConeSize) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map vertex %D\n",tv);
677990b157c4SStefano Zampini 
678090b157c4SStefano Zampini               ierr = PetscSectionGetOffset(coordSection, cone[p], &voff);CHKERRQ(ierr);
678190b157c4SStefano Zampini               for (d = 0; d < spaceDim; ++d) {
678290b157c4SStefano Zampini                 coordsNewAux[d] += coords[ccoff[p]+d];
678390b157c4SStefano Zampini                 if (!cellfound && coords[voff+d] != coords[ccoff[p]+d]) locv = PETSC_FALSE;
678490b157c4SStefano Zampini               }
678590b157c4SStefano Zampini               if (locv && !cellfound) {
678690b157c4SStefano Zampini                 cellfound = PETSC_TRUE;
678790b157c4SStefano Zampini                 copyoff   = PETSC_TRUE;
678890b157c4SStefano Zampini               }
678990b157c4SStefano Zampini             }
67909fc2a3f3SStefano Zampini             for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize;
679190b157c4SStefano Zampini 
679290b157c4SStefano Zampini             /* Found a valid face for the "vertex" part of the Section (physical space)
679390b157c4SStefano Zampini                i.e., a face that has at least one corner in the physical space */
679490b157c4SStefano Zampini             if (copyoff) for (p = 0; p < coneSize; ++p) off[p] = ccoff[p];
67959fc2a3f3SStefano Zampini           }
679690b157c4SStefano Zampini 
679790b157c4SStefano Zampini           /* Localize new coordinates on each refined cell */
679890b157c4SStefano Zampini           for (v = 0; v < rStarSize*2; v += 2) {
679990b157c4SStefano Zampini             if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew) && parentId[rStar[v]-cStartNew] == cell) {
68009fc2a3f3SStefano Zampini               PetscInt       *rcone = NULL, rclosureSize, lid, rcdof, rcoff;
680190b157c4SStefano Zampini               const PetscInt  rcell = rStar[v];
680290b157c4SStefano Zampini 
68039fc2a3f3SStefano Zampini               ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr);
68049fc2a3f3SStefano Zampini               if (!rcdof) continue;
68059fc2a3f3SStefano Zampini               ierr = PetscSectionGetOffset(coordSectionNew, rcell, &rcoff);CHKERRQ(ierr);
680690b157c4SStefano Zampini               ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr);
680790b157c4SStefano Zampini               for (p = 0, lid = 0; p < rclosureSize*2; p += 2) {
680890b157c4SStefano Zampini                 if (rcone[p] == newv) {
68099fc2a3f3SStefano Zampini                   for (d = 0; d < spaceDim; d++) coordsNew[rcoff + lid*spaceDim + d] = coordsNewAux[d];
681090b157c4SStefano Zampini                   break;
681190b157c4SStefano Zampini                 }
681290b157c4SStefano Zampini                 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++;
681390b157c4SStefano Zampini               }
681490b157c4SStefano Zampini               ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr);
681590b157c4SStefano Zampini               if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv);
681690b157c4SStefano Zampini             }
681790b157c4SStefano Zampini           }
68189fc2a3f3SStefano Zampini           ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr);
681990b157c4SStefano Zampini         }
682090b157c4SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
682190b157c4SStefano Zampini         if (!cellfound) {
68221072f78bSStefano Zampini           /* Could not find a valid face for the vertex part, we will get this vertex later (final reduction) */
68231072f78bSStefano Zampini           needcoords = PETSC_TRUE;
682490b157c4SStefano Zampini           coneSize   = 0;
682590b157c4SStefano Zampini         }
682690b157c4SStefano Zampini       } else {
6827b5da9499SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) {
6828b5da9499SMatthew G. Knepley           ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
6829b5da9499SMatthew G. Knepley         }
683090b157c4SStefano Zampini       }
6831b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
683290b157c4SStefano Zampini       if (coneSize) {
68331072f78bSStefano Zampini         for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
68342e17dfb7SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);}
6835f1d7821bSLawrence Mitchell         for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
68361072f78bSStefano Zampini       } else {
68371072f78bSStefano Zampini         for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL;
683890b157c4SStefano Zampini       }
6839b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
6840b5da9499SMatthew G. Knepley     }
6841e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_2D:
68429b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
68439b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
6844383c10e6SMatthew G. Knepley   case REFINER_SIMPLEX_1D:
6845b5da9499SMatthew G. Knepley     /* Cell vertices have the average of corner coordinates */
684627fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
68472ed5862eSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (dim > 1 ? (eMax - eStart) : 0) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0);
6848b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
68499fc2a3f3SStefano Zampini       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d, cdof = 0;
6850b5da9499SMatthew G. Knepley 
6851b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
6852b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
6853b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
6854b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
6855b5da9499SMatthew G. Knepley       }
685690b157c4SStefano Zampini       if (localize) {
68579fc2a3f3SStefano Zampini         ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr);
68589fc2a3f3SStefano Zampini       }
68599fc2a3f3SStefano Zampini       if (cdof) {
686090b157c4SStefano Zampini         PetscInt coff;
686190b157c4SStefano Zampini 
686290b157c4SStefano Zampini         ierr = PetscSectionGetOffset(coordSection, c, &coff);CHKERRQ(ierr);
686390b157c4SStefano Zampini         for (v = 0; v < coneSize; ++v) off[v] = spaceDim*v + coff;
686490b157c4SStefano Zampini       } else {
6865b5da9499SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) {
6866b5da9499SMatthew G. Knepley           ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
6867b5da9499SMatthew G. Knepley         }
686890b157c4SStefano Zampini       }
6869b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
6870f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
68712e17dfb7SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);}
6872f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
6873b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
68749fc2a3f3SStefano Zampini 
687590b157c4SStefano Zampini       /* Localize new coordinates on each refined cell */
68769fc2a3f3SStefano Zampini       if (cdof) {
687790b157c4SStefano Zampini         PetscInt *rStar = NULL, rStarSize;
687890b157c4SStefano Zampini 
687990b157c4SStefano Zampini         ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
688090b157c4SStefano Zampini         for (v = 0; v < rStarSize*2; v += 2) {
688190b157c4SStefano Zampini           if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew)) {
68829fc2a3f3SStefano Zampini             PetscInt *cone = NULL, closureSize, lid, coff, rc, rcdof;
688390b157c4SStefano Zampini 
688490b157c4SStefano Zampini             rc   = rStar[v];
68859fc2a3f3SStefano Zampini             ierr = PetscSectionGetDof(coordSectionNew, rc, &rcdof);CHKERRQ(ierr);
68869fc2a3f3SStefano Zampini             if (!rcdof) continue;
688790b157c4SStefano Zampini             ierr = PetscSectionGetOffset(coordSectionNew, rc, &coff);CHKERRQ(ierr);
688890b157c4SStefano Zampini             ierr = DMPlexGetTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
688990b157c4SStefano Zampini             for (p = 0, lid = 0; p < closureSize*2; p += 2) {
689090b157c4SStefano Zampini               if (cone[p] == newv) {
689190b157c4SStefano Zampini                 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNew[offnew + d];
689290b157c4SStefano Zampini                 break;
689390b157c4SStefano Zampini               }
689490b157c4SStefano Zampini               if (cone[p] >= vStartNew && cone[p] < vEndNew) lid++;
689590b157c4SStefano Zampini             }
689690b157c4SStefano Zampini             if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv);
689790b157c4SStefano Zampini             ierr = DMPlexRestoreTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
689890b157c4SStefano Zampini           }
689990b157c4SStefano Zampini         }
690090b157c4SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
690190b157c4SStefano Zampini       }
6902b5da9499SMatthew G. Knepley     }
69039b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
69049b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
69059b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
69069b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
6907b5da9499SMatthew G. Knepley     /* Edge vertices have the average of endpoint coordinates */
6908b5da9499SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
6909b5da9499SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (e - eStart);
6910b5da9499SMatthew G. Knepley       const PetscInt *cone;
6911b5da9499SMatthew G. Knepley       PetscInt        coneSize, offA, offB, offnew, d;
6912b5da9499SMatthew G. Knepley 
6913b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr);
6914b5da9499SMatthew G. Knepley       if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize);
6915b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
691690b157c4SStefano Zampini       if (localize) {
69173548e9b6SStefano Zampini         PetscInt   coff, toffA = -1, toffB = -1, voffA, voffB;
691890b157c4SStefano Zampini         PetscInt  *eStar = NULL, eStarSize;
691990b157c4SStefano Zampini         PetscInt  *rStar = NULL, rStarSize;
69209fc2a3f3SStefano Zampini         PetscBool  cellfound = PETSC_FALSE;
692190b157c4SStefano Zampini 
692290b157c4SStefano Zampini         offA = offB = -1;
692390b157c4SStefano Zampini         ierr = PetscSectionGetOffset(coordSection, cone[0], &voffA);CHKERRQ(ierr);
692490b157c4SStefano Zampini         ierr = PetscSectionGetOffset(coordSection, cone[1], &voffB);CHKERRQ(ierr);
692590b157c4SStefano Zampini         ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr);
692690b157c4SStefano Zampini         ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
692790b157c4SStefano Zampini         for (v = 0; v < eStarSize*2; v += 2) {
692890b157c4SStefano Zampini           if ((eStar[v] >= cStart) && (eStar[v] < cEnd)) {
692990b157c4SStefano Zampini             PetscScalar     coordsNewAux[3];
693090b157c4SStefano Zampini             PetscInt       *cellCone = NULL;
69319fc2a3f3SStefano Zampini             PetscInt        cellClosureSize, s, cv, cdof;
693290b157c4SStefano Zampini             PetscBool       locvA = PETSC_TRUE, locvB = PETSC_TRUE;
693390b157c4SStefano Zampini             const PetscInt  cell = eStar[v];
693490b157c4SStefano Zampini 
69359fc2a3f3SStefano Zampini             ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr);
69369fc2a3f3SStefano Zampini             if (!cdof) {
69379fc2a3f3SStefano Zampini               /* Found a valid edge for the "vertex" part of the Section */
69389fc2a3f3SStefano Zampini               offA = voffA;
69399fc2a3f3SStefano Zampini               offB = voffB;
69409fc2a3f3SStefano Zampini               cellfound = PETSC_TRUE;
69419fc2a3f3SStefano Zampini             } else {
694290b157c4SStefano Zampini               ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr);
694390b157c4SStefano Zampini               ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr);
694490b157c4SStefano Zampini               for (s = 0, cv = 0; s < cellClosureSize*2; s += 2) {
694590b157c4SStefano Zampini                 const PetscInt point = cellCone[s];
694690b157c4SStefano Zampini                 if ((point >= vStart) && (point < vEnd)) {
694790b157c4SStefano Zampini                   if (point == cone[0]) toffA = spaceDim*cv + coff;
694890b157c4SStefano Zampini                   else if (point == cone[1]) toffB = spaceDim*cv + coff;
694990b157c4SStefano Zampini                   cv++;
695090b157c4SStefano Zampini                 }
695190b157c4SStefano Zampini               }
695290b157c4SStefano Zampini               ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr);
695390b157c4SStefano Zampini               for (d = 0; d < spaceDim; ++d) {
695490b157c4SStefano Zampini                 coordsNewAux[d] = 0.5*(coords[toffA+d] + coords[toffB+d]);
695590b157c4SStefano Zampini                 if (coords[toffA+d] != coords[voffA+d]) locvA = PETSC_FALSE;
695690b157c4SStefano Zampini                 if (coords[toffB+d] != coords[voffB+d]) locvB = PETSC_FALSE;
695790b157c4SStefano Zampini               }
695890b157c4SStefano Zampini               /* Found a valid edge for the "vertex" part of the Section */
69599fc2a3f3SStefano Zampini               if (!cellfound && (locvA || locvB)) {
69609fc2a3f3SStefano Zampini                 cellfound = PETSC_TRUE;
69619fc2a3f3SStefano Zampini                 offA = toffA;
69629fc2a3f3SStefano Zampini                 offB = toffB;
69639fc2a3f3SStefano Zampini               }
69649fc2a3f3SStefano Zampini             }
696590b157c4SStefano Zampini 
696690b157c4SStefano Zampini             /* Localize new coordinates on each refined cell */
696790b157c4SStefano Zampini             for (s = 0; s < rStarSize*2; s += 2) {
696890b157c4SStefano Zampini               if ((rStar[s] >= cStartNew) && (rStar[s] < cEndNew) && parentId[rStar[s]-cStartNew] == cell) {
69699fc2a3f3SStefano Zampini                 PetscInt       *rcone = NULL, rclosureSize, lid, p, rcdof;
697090b157c4SStefano Zampini                 const PetscInt  rcell = rStar[s];
697190b157c4SStefano Zampini 
69729fc2a3f3SStefano Zampini                 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr);
69739fc2a3f3SStefano Zampini                 if (!rcdof) continue;
697490b157c4SStefano Zampini                 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &coff);CHKERRQ(ierr);
697590b157c4SStefano Zampini                 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr);
697690b157c4SStefano Zampini                 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) {
697790b157c4SStefano Zampini                   if (rcone[p] == newv) {
697890b157c4SStefano Zampini                     for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNewAux[d];
697990b157c4SStefano Zampini                     break;
698090b157c4SStefano Zampini                   }
698190b157c4SStefano Zampini                   if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++;
698290b157c4SStefano Zampini                 }
698390b157c4SStefano Zampini                 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr);
698490b157c4SStefano Zampini                 if (p == rclosureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv);
698590b157c4SStefano Zampini               }
698690b157c4SStefano Zampini             }
698790b157c4SStefano Zampini           }
698890b157c4SStefano Zampini         }
698990b157c4SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr);
699090b157c4SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
69919fc2a3f3SStefano Zampini         if (!cellfound) {
69921072f78bSStefano Zampini           /* Could not find a valid edge for the vertex part, we will get this vertex later (final reduction) */
69931072f78bSStefano Zampini           needcoords = PETSC_TRUE;
699490b157c4SStefano Zampini         }
699590b157c4SStefano Zampini       } else {
6996b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr);
6997b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr);
699890b157c4SStefano Zampini       }
6999b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
700090b157c4SStefano Zampini       if (offA != -1 && offB != -1) {
70012e17dfb7SMatthew G. Knepley         ierr = DMLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr);
7002f1d7821bSLawrence Mitchell         for (d = 0; d < spaceDim; ++d) {
7003a96104c9SMatthew G. Knepley           coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]);
7004b5da9499SMatthew G. Knepley         }
700590b157c4SStefano Zampini       } else {
70061072f78bSStefano Zampini         for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL;
700790b157c4SStefano Zampini       }
7008b5da9499SMatthew G. Knepley     }
700975d3a19aSMatthew G. Knepley     /* Old vertices have the same coordinates */
701075d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
701175d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (v - vStart);
701275d3a19aSMatthew G. Knepley       PetscInt       off, offnew, d;
701375d3a19aSMatthew G. Knepley 
701475d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr);
701575d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
7016f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) {
701775d3a19aSMatthew G. Knepley         coordsNew[offnew+d] = coords[off+d];
701875d3a19aSMatthew G. Knepley       }
701990b157c4SStefano Zampini 
702090b157c4SStefano Zampini       /* Localize new coordinates on each refined cell */
702190b157c4SStefano Zampini       if (localize) {
702290b157c4SStefano Zampini         PetscInt  p;
702390b157c4SStefano Zampini         PetscInt *rStar = NULL, rStarSize;
702490b157c4SStefano Zampini 
702590b157c4SStefano Zampini         ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
702690b157c4SStefano Zampini         for (p = 0; p < rStarSize*2; p += 2) {
702790b157c4SStefano Zampini           if ((rStar[p] >= cStartNew) && (rStar[p] < cEndNew)) {
702890b157c4SStefano Zampini             PetscScalar  ocoords[3];
70299fc2a3f3SStefano Zampini             PetscInt    *cone = NULL, closureSize, lid, coff, s, oc, cdof;
703090b157c4SStefano Zampini 
703190b157c4SStefano Zampini             c    = rStar[p];
703290b157c4SStefano Zampini             oc   = parentId[c-cStartNew];
70339fc2a3f3SStefano Zampini             ierr = PetscSectionGetDof(coordSectionNew, c, &cdof);CHKERRQ(ierr);
70349fc2a3f3SStefano Zampini             if (!cdof) continue;
70359fc2a3f3SStefano Zampini             ierr = PetscSectionGetDof(coordSection, oc, &cdof);CHKERRQ(ierr);
70369fc2a3f3SStefano Zampini             if (!cdof) continue;
703790b157c4SStefano Zampini             ierr = PetscSectionGetOffset(coordSection, oc, &coff);CHKERRQ(ierr);
703890b157c4SStefano Zampini             ierr = DMPlexGetTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
703990b157c4SStefano Zampini             for (s = 0, lid = 0; s < closureSize*2; s += 2) {
704090b157c4SStefano Zampini               if (cone[s] == v) {
704190b157c4SStefano Zampini                 for (d = 0; d < spaceDim; d++) ocoords[d] = coords[coff + lid*spaceDim + d];
704290b157c4SStefano Zampini                 break;
704390b157c4SStefano Zampini               }
704490b157c4SStefano Zampini               if (cone[s] >= vStart && cone[s] < vEnd) lid++;
704590b157c4SStefano Zampini             }
704690b157c4SStefano Zampini             if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map old vertex %D\n",v);
704790b157c4SStefano Zampini             ierr = DMPlexRestoreTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
704890b157c4SStefano Zampini 
704990b157c4SStefano Zampini             ierr = PetscSectionGetOffset(coordSectionNew, c, &coff);CHKERRQ(ierr);
705090b157c4SStefano Zampini             ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
705190b157c4SStefano Zampini             for (s = 0, lid = 0; s < closureSize*2; s += 2) {
705290b157c4SStefano Zampini               if (cone[s] == newv) {
705390b157c4SStefano Zampini                 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = ocoords[d];
705490b157c4SStefano Zampini                 break;
705590b157c4SStefano Zampini               }
705690b157c4SStefano Zampini               if (cone[s] >= vStartNew && cone[s] < vEndNew) lid++;
705790b157c4SStefano Zampini             }
705890b157c4SStefano Zampini             if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv);
705990b157c4SStefano Zampini             ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
706090b157c4SStefano Zampini           }
706190b157c4SStefano Zampini         }
706290b157c4SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
706390b157c4SStefano Zampini       }
706475d3a19aSMatthew G. Knepley     }
7065b5da9499SMatthew G. Knepley     break;
7066b5da9499SMatthew G. Knepley   default:
7067b5da9499SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
706875d3a19aSMatthew G. Knepley   }
706975d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr);
707075d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
707175d3a19aSMatthew G. Knepley   ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr);
707290b157c4SStefano Zampini 
707390b157c4SStefano Zampini   /* Final reduction (if needed) if we are localizing */
707490b157c4SStefano Zampini   if (localize) {
70751072f78bSStefano Zampini     PetscBool gred;
707690b157c4SStefano Zampini 
70771072f78bSStefano Zampini     ierr = MPIU_Allreduce(&needcoords, &gred, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)rdm));CHKERRQ(ierr);
707890b157c4SStefano Zampini     if (gred) {
707990b157c4SStefano Zampini       DM                 cdm;
70801072f78bSStefano Zampini       Vec                aux;
70811072f78bSStefano Zampini       PetscSF            sf;
70821072f78bSStefano Zampini       const PetscScalar *lArray;
70839fc2a3f3SStefano Zampini       PetscScalar       *gArray;
708490b157c4SStefano Zampini 
708590b157c4SStefano Zampini       ierr = DMGetCoordinateDM(rdm, &cdm);CHKERRQ(ierr);
708690b157c4SStefano Zampini       ierr = DMCreateGlobalVector(cdm, &aux);CHKERRQ(ierr);
70871072f78bSStefano Zampini       ierr = DMGetDefaultSF(cdm, &sf);CHKERRQ(ierr);
70881072f78bSStefano Zampini       ierr = VecGetArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr);
70891072f78bSStefano Zampini       ierr = VecSet(aux, PETSC_MIN_REAL);CHKERRQ(ierr);
70901072f78bSStefano Zampini       ierr = VecGetArray(aux, &gArray);CHKERRQ(ierr);
70911072f78bSStefano Zampini       ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr);
70921072f78bSStefano Zampini       ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr);
70931072f78bSStefano Zampini       ierr = VecRestoreArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr);
70941072f78bSStefano Zampini       ierr = VecRestoreArray(aux, &gArray);CHKERRQ(ierr);
709590b157c4SStefano Zampini       ierr = DMGlobalToLocalBegin(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr);
709690b157c4SStefano Zampini       ierr = DMGlobalToLocalEnd(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr);
709790b157c4SStefano Zampini       ierr = VecDestroy(&aux);CHKERRQ(ierr);
709890b157c4SStefano Zampini     }
709990b157c4SStefano Zampini   }
710075d3a19aSMatthew G. Knepley   ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr);
710175d3a19aSMatthew G. Knepley   ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr);
710290b157c4SStefano Zampini   ierr = PetscFree(parentId);CHKERRQ(ierr);
710375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
710475d3a19aSMatthew G. Knepley }
710575d3a19aSMatthew G. Knepley 
7106963fc26aSMatthew G. Knepley /*@
7107963fc26aSMatthew G. Knepley   DMPlexCreateProcessSF - Create an SF which just has process connectivity
7108963fc26aSMatthew G. Knepley 
7109963fc26aSMatthew G. Knepley   Collective on DM
7110963fc26aSMatthew G. Knepley 
7111963fc26aSMatthew G. Knepley   Input Parameters:
7112963fc26aSMatthew G. Knepley + dm      - The DM
7113963fc26aSMatthew G. Knepley - sfPoint - The PetscSF which encodes point connectivity
7114963fc26aSMatthew G. Knepley 
7115963fc26aSMatthew G. Knepley   Output Parameters:
7116963fc26aSMatthew G. Knepley + processRanks - A list of process neighbors, or NULL
7117963fc26aSMatthew G. Knepley - sfProcess    - An SF encoding the process connectivity, or NULL
7118963fc26aSMatthew G. Knepley 
7119963fc26aSMatthew G. Knepley   Level: developer
7120963fc26aSMatthew G. Knepley 
7121963fc26aSMatthew G. Knepley .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF()
7122963fc26aSMatthew G. Knepley @*/
7123963fc26aSMatthew G. Knepley PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
712475d3a19aSMatthew G. Knepley {
712575d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, l;
712675d3a19aSMatthew G. Knepley   const PetscInt    *localPoints;
712775d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
712875d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
712975d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
713075d3a19aSMatthew G. Knepley   PetscInt          *ranks, *ranksNew;
71319852e123SBarry Smith   PetscMPIInt        size;
713275d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
713375d3a19aSMatthew G. Knepley 
713475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
7135963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7136963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2);
7137963fc26aSMatthew G. Knepley   if (processRanks) {PetscValidPointer(processRanks, 3);}
7138963fc26aSMatthew G. Knepley   if (sfProcess)    {PetscValidPointer(sfProcess, 4);}
71399852e123SBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr);
714075d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
7141785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr);
714275d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
714375d3a19aSMatthew G. Knepley     ranks[l] = remotePoints[l].rank;
714475d3a19aSMatthew G. Knepley   }
714575d3a19aSMatthew G. Knepley   ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr);
7146785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr);
7147785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr);
7148785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr);
714975d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
715075d3a19aSMatthew G. Knepley     ranksNew[l]              = ranks[l];
715175d3a19aSMatthew G. Knepley     localPointsNew[l]        = l;
715275d3a19aSMatthew G. Knepley     remotePointsNew[l].index = 0;
715375d3a19aSMatthew G. Knepley     remotePointsNew[l].rank  = ranksNew[l];
715475d3a19aSMatthew G. Knepley   }
715575d3a19aSMatthew G. Knepley   ierr = PetscFree(ranks);CHKERRQ(ierr);
7156963fc26aSMatthew G. Knepley   if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);}
7157963fc26aSMatthew G. Knepley   else              {ierr = PetscFree(ranksNew);CHKERRQ(ierr);}
7158963fc26aSMatthew G. Knepley   if (sfProcess) {
715975d3a19aSMatthew G. Knepley     ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr);
7160963fc26aSMatthew G. Knepley     ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr);
716175d3a19aSMatthew G. Knepley     ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr);
71629852e123SBarry Smith     ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
7163963fc26aSMatthew G. Knepley   }
716475d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
716575d3a19aSMatthew G. Knepley }
716675d3a19aSMatthew G. Knepley 
716786150812SJed Brown static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
716875d3a19aSMatthew G. Knepley {
716975d3a19aSMatthew G. Knepley   PetscSF            sf, sfNew, sfProcess;
717075d3a19aSMatthew G. Knepley   IS                 processRanks;
717175d3a19aSMatthew G. Knepley   MPI_Datatype       depthType;
717275d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, numLeavesNew = 0, l, m;
717375d3a19aSMatthew G. Knepley   const PetscInt    *localPoints, *neighbors;
717475d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
717575d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
717675d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
717775d3a19aSMatthew G. Knepley   PetscInt          *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew;
717837d81139SMatthew G. Knepley   PetscInt           ldepth, depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n;
71797ba685a0SMatthew G. Knepley   PetscInt           cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
718075d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
718175d3a19aSMatthew G. Knepley 
718275d3a19aSMatthew G. Knepley   PetscFunctionBegin;
718375d3a19aSMatthew G. Knepley   ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr);
718437d81139SMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &ldepth);CHKERRQ(ierr);
718537d81139SMatthew G. Knepley   ierr = MPIU_Allreduce(&ldepth, &depth, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr);
718637d81139SMatthew G. Knepley   if ((ldepth >= 0) && (depth != ldepth)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent Plex depth %d != %d", ldepth, depth);
718775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
718875d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
718975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
719075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
719175d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
7192add09238SMatthew G. Knepley   cMax = cMax < 0 ? cEnd : cMax;
7193add09238SMatthew G. Knepley   fMax = fMax < 0 ? fEnd : fMax;
7194add09238SMatthew G. Knepley   eMax = eMax < 0 ? eEnd : eMax;
71953478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
719675d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
719775d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr);
7198add09238SMatthew G. Knepley   /* Calculate size of new SF */
719975d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
720075d3a19aSMatthew G. Knepley   if (numRoots < 0) PetscFunctionReturn(0);
720175d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
720275d3a19aSMatthew G. Knepley     const PetscInt p = localPoints[l];
720375d3a19aSMatthew G. Knepley 
720475d3a19aSMatthew G. Knepley     switch (refiner) {
72050314a74cSLawrence Mitchell     case REFINER_SIMPLEX_1D:
72060314a74cSLawrence Mitchell       if ((p >= vStart) && (p < vEnd)) {
72070314a74cSLawrence Mitchell         /* Interior vertices stay the same */
72080314a74cSLawrence Mitchell         ++numLeavesNew;
72090314a74cSLawrence Mitchell       } else if ((p >= cStart && p < cMax)) {
72100314a74cSLawrence Mitchell         /* Interior cells add new cells and interior vertices */
72110314a74cSLawrence Mitchell         numLeavesNew += 2 + 1;
72120314a74cSLawrence Mitchell       }
72130314a74cSLawrence Mitchell       break;
72149b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_2D:
72159b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_2D:
7216a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
7217a97b51b8SMatthew G. Knepley         /* Interior vertices stay the same */
7218a97b51b8SMatthew G. Knepley         ++numLeavesNew;
7219a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
7220a97b51b8SMatthew G. Knepley         /* Interior faces add new faces and vertex */
7221a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
7222a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
7223a97b51b8SMatthew G. Knepley         /* Hybrid faces stay the same */
7224a97b51b8SMatthew G. Knepley         ++numLeavesNew;
7225a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
7226a97b51b8SMatthew G. Knepley         /* Interior cells add new cells and interior faces */
7227a97b51b8SMatthew G. Knepley         numLeavesNew += 4 + 3;
7228a97b51b8SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
7229a97b51b8SMatthew G. Knepley         /* Hybrid cells add new cells and hybrid face */
7230a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
7231a97b51b8SMatthew G. Knepley       }
7232a97b51b8SMatthew G. Knepley       break;
7233e5337592SStefano Zampini     case REFINER_SIMPLEX_TO_HEX_2D:
7234e5337592SStefano Zampini       if ((p >= vStart) && (p < vEnd)) {
7235e5337592SStefano Zampini         /* Interior vertices stay the same */
7236e5337592SStefano Zampini         ++numLeavesNew;
7237e5337592SStefano Zampini       } else if ((p >= fStart) && (p < fEnd)) {
7238e5337592SStefano Zampini         /* Interior faces add new faces and vertex */
7239e5337592SStefano Zampini         numLeavesNew += 2 + 1;
7240e5337592SStefano Zampini       } else if ((p >= cStart) && (p < cEnd)) {
7241e5337592SStefano Zampini         /* Interior cells add new cells, interior faces, and vertex */
7242e5337592SStefano Zampini         numLeavesNew += 3 + 3 + 1;
7243e5337592SStefano Zampini       }
7244e5337592SStefano Zampini       break;
72459b1a0e7fSLawrence Mitchell     case REFINER_HEX_2D:
72469b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_2D:
7247a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
7248a97b51b8SMatthew G. Knepley         /* Interior vertices stay the same */
7249a97b51b8SMatthew G. Knepley         ++numLeavesNew;
7250a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
7251a97b51b8SMatthew G. Knepley         /* Interior faces add new faces and vertex */
7252a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
7253a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
7254a97b51b8SMatthew G. Knepley         /* Hybrid faces stay the same */
7255a97b51b8SMatthew G. Knepley         ++numLeavesNew;
7256a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
7257a97b51b8SMatthew G. Knepley         /* Interior cells add new cells, interior faces, and vertex */
7258a97b51b8SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
7259a97b51b8SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
7260a97b51b8SMatthew G. Knepley         /* Hybrid cells add new cells and hybrid face */
7261a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
7262a97b51b8SMatthew G. Knepley       }
7263a97b51b8SMatthew G. Knepley       break;
72649b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_3D:
72659b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_3D:
72666ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
72676ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
72686ce3c06aSMatthew G. Knepley         ++numLeavesNew;
72696ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
72706ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
72716ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
72726ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
72736ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
72746ce3c06aSMatthew G. Knepley         ++numLeavesNew;
72756ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
72766ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
72776ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
72786ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
72796ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
72806ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
72816ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
72826ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
72836ce3c06aSMatthew G. Knepley         numLeavesNew += 8 + 8 + 1;
72846ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
72856ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
72866ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
72876ce3c06aSMatthew G. Knepley       }
72886ce3c06aSMatthew G. Knepley       break;
7289e5337592SStefano Zampini     case REFINER_SIMPLEX_TO_HEX_3D:
7290e5337592SStefano Zampini       if ((p >= vStart) && (p < vEnd)) {
7291e5337592SStefano Zampini         /* Interior vertices stay the same */
7292e5337592SStefano Zampini         ++numLeavesNew;
7293e5337592SStefano Zampini       } else if ((p >= eStart) && (p < eEnd)) {
7294e5337592SStefano Zampini         /* Interior edges add new edges and vertex */
7295e5337592SStefano Zampini         numLeavesNew += 2 + 1;
7296e5337592SStefano Zampini       } else if ((p >= fStart) && (p < fEnd)) {
7297e5337592SStefano Zampini         /* Interior faces add new faces, edges and a vertex */
7298e5337592SStefano Zampini         numLeavesNew += 3 + 3 + 1;
7299e5337592SStefano Zampini       } else if ((p >= cStart) && (p < cEnd)) {
7300e5337592SStefano Zampini         /* Interior cells add new cells, faces, edges and a vertex */
7301e5337592SStefano Zampini         numLeavesNew += 4 + 6 + 4 + 1;
7302e5337592SStefano Zampini       }
7303e5337592SStefano Zampini       break;
73049b1a0e7fSLawrence Mitchell     case REFINER_HEX_3D:
73059b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_3D:
730627fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
730727fcede3SMatthew G. Knepley         /* Old vertices stay the same */
730827fcede3SMatthew G. Knepley         ++numLeavesNew;
730927fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
731027fcede3SMatthew G. Knepley         /* Interior edges add new edges, and vertex */
731127fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
731227fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
731327fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
731427fcede3SMatthew G. Knepley         ++numLeavesNew;
731527fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
731627fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
731727fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
731827fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
731927fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
732027fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
732127fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
732227fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
732327fcede3SMatthew G. Knepley         numLeavesNew += 8 + 12 + 6 + 1;
732427fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
732527fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
732627fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
732727fcede3SMatthew G. Knepley       }
732827fcede3SMatthew G. Knepley       break;
732975d3a19aSMatthew G. Knepley     default:
733075d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
733175d3a19aSMatthew G. Knepley     }
733275d3a19aSMatthew G. Knepley   }
733375d3a19aSMatthew G. Knepley   /* Communicate depthSizes for each remote rank */
733475d3a19aSMatthew G. Knepley   ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr);
733575d3a19aSMatthew G. Knepley   ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr);
7336dcca6d9dSJed Brown   ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr);
7337dcca6d9dSJed Brown   ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr);
733875d3a19aSMatthew G. Knepley   ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr);
733975d3a19aSMatthew G. Knepley   ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr);
734075d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
734175d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
734275d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
734375d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr);
734475d3a19aSMatthew G. Knepley   }
734575d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cMax;
734675d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vMax;
734775d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fMax;
734875d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eMax;
734975d3a19aSMatthew G. Knepley 
735075d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
735175d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
735275d3a19aSMatthew G. Knepley 
735375d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cEnd - cStart;
735475d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vEnd - vStart;
735575d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fEnd - fStart;
735675d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eEnd - eStart;
735775d3a19aSMatthew G. Knepley 
735875d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
735975d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
736075d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
736175d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr);
73620252e7f5SMatthew 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];
73630252e7f5SMatthew 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];
73640252e7f5SMatthew 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];
736575d3a19aSMatthew G. Knepley   }
736675d3a19aSMatthew G. Knepley   ierr = MPI_Type_free(&depthType);CHKERRQ(ierr);
736775d3a19aSMatthew G. Knepley   ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr);
736875d3a19aSMatthew G. Knepley   /* Calculate new point SF */
7369785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr);
7370785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr);
737175d3a19aSMatthew G. Knepley   ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr);
737275d3a19aSMatthew G. Knepley   for (l = 0, m = 0; l < numLeaves; ++l) {
737375d3a19aSMatthew G. Knepley     PetscInt    p     = localPoints[l];
737475d3a19aSMatthew G. Knepley     PetscInt    rp    = remotePoints[l].index, n;
737575d3a19aSMatthew G. Knepley     PetscMPIInt rrank = remotePoints[l].rank;
737675d3a19aSMatthew G. Knepley 
737775d3a19aSMatthew G. Knepley     ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr);
737875d3a19aSMatthew G. Knepley     if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank);
737975d3a19aSMatthew G. Knepley     switch (refiner) {
73800314a74cSLawrence Mitchell     case REFINER_SIMPLEX_1D:
73810314a74cSLawrence Mitchell       if ((p >= vStart) && (p < vEnd)) {
73820314a74cSLawrence Mitchell         /* Old vertices stay the same */
73830314a74cSLawrence Mitchell         localPointsNew[m]        = vStartNew     + (p  - vStart);
73840314a74cSLawrence Mitchell         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
73850314a74cSLawrence Mitchell         remotePointsNew[m].rank  = rrank;
73860314a74cSLawrence Mitchell         ++m;
73870314a74cSLawrence Mitchell       } else if ((p >= cStart) && (p < cMax)) {
73880314a74cSLawrence Mitchell         /* Old interior cells add new cells and vertex */
73890314a74cSLawrence Mitchell         for (r = 0; r < 2; ++r, ++m) {
73900314a74cSLawrence Mitchell           localPointsNew[m]        = cStartNew     + (p  - cStart)*2     + r;
73910314a74cSLawrence Mitchell           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r;
73920314a74cSLawrence Mitchell           remotePointsNew[m].rank  = rrank;
73930314a74cSLawrence Mitchell         }
73940314a74cSLawrence Mitchell         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - cStart);
73950314a74cSLawrence Mitchell         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]);
73960314a74cSLawrence Mitchell         remotePointsNew[m].rank  = rrank;
73970314a74cSLawrence Mitchell         ++m;
73980314a74cSLawrence Mitchell       }
73990314a74cSLawrence Mitchell       break;
74009b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_2D:
74019b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_2D:
740275d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
740375d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
740475d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
740575d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
740675d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
740775d3a19aSMatthew G. Knepley         ++m;
740875d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
740975d3a19aSMatthew G. Knepley         /* Old interior faces add new faces and vertex */
741075d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
741175d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
741275d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
741375d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
741475d3a19aSMatthew G. Knepley         }
7415add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
7416add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
7417add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
7418add09238SMatthew G. Knepley         ++m;
741975d3a19aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
742075d3a19aSMatthew G. Knepley         /* Old hybrid faces stay the same */
742175d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
742275d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
742375d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
742475d3a19aSMatthew G. Knepley         ++m;
742575d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
742675d3a19aSMatthew G. Knepley         /* Old interior cells add new cells and interior faces */
742775d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
742875d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
742975d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
743075d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
743175d3a19aSMatthew G. Knepley         }
743275d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
743375d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*3     + r;
743475d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r;
743575d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
743675d3a19aSMatthew G. Knepley         }
7437add09238SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
743875d3a19aSMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
743975d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
744075d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
744175d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
744275d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
744375d3a19aSMatthew G. Knepley         }
744475d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*3     + (p  - cMax);
744575d3a19aSMatthew 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]);
744675d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
744775d3a19aSMatthew G. Knepley         ++m;
744875d3a19aSMatthew G. Knepley       }
744975d3a19aSMatthew G. Knepley       break;
7450e5337592SStefano Zampini     case REFINER_SIMPLEX_TO_HEX_2D:
7451e5337592SStefano Zampini       if ((p >= vStart) && (p < vEnd)) {
7452e5337592SStefano Zampini         /* Old vertices stay the same */
7453e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (p  - vStart);
7454e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
7455e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7456e5337592SStefano Zampini         ++m;
7457e5337592SStefano Zampini       } else if ((p >= fStart) && (p < fEnd)) {
7458e5337592SStefano Zampini         /* Old interior faces add new faces and vertex */
7459e5337592SStefano Zampini         for (r = 0; r < 2; ++r, ++m) {
7460e5337592SStefano Zampini           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
7461e5337592SStefano Zampini           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
7462e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7463e5337592SStefano Zampini         }
7464e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
7465e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
7466e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7467e5337592SStefano Zampini         ++m;
7468e5337592SStefano Zampini       } else if ((p >= cStart) && (p < cEnd)) {
7469e5337592SStefano Zampini         /* Old interior cells add new cells, interior faces, and a vertex */
7470e5337592SStefano Zampini         for (r = 0; r < 3; ++r, ++m) {
7471e5337592SStefano Zampini           localPointsNew[m]        = cStartNew     + (p  - cStart)*3     + r;
7472e5337592SStefano Zampini           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*3 + r;
7473e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7474e5337592SStefano Zampini         }
7475e5337592SStefano Zampini         for (r = 0; r < 3; ++r, ++m) {
7476e5337592SStefano Zampini           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*2                    + (p  - cStart)*3     + r;
7477e5337592SStefano Zampini           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r;
7478e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7479e5337592SStefano Zampini         }
7480e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (fEnd - fStart)                    + (p  - cStart);
7481e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]);
7482e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7483e5337592SStefano Zampini         ++m;
7484e5337592SStefano Zampini       }
7485e5337592SStefano Zampini       break;
74869b1a0e7fSLawrence Mitchell     case REFINER_HEX_2D:
74879b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_2D:
7488a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
7489a97b51b8SMatthew G. Knepley         /* Old vertices stay the same */
7490a97b51b8SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
7491a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
7492a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
7493a97b51b8SMatthew G. Knepley         ++m;
7494a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
7495a97b51b8SMatthew G. Knepley         /* Old interior faces add new faces and vertex */
7496a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
7497a97b51b8SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
7498a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
7499a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
7500a97b51b8SMatthew G. Knepley         }
7501add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
7502add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
7503add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
7504add09238SMatthew G. Knepley         ++m;
7505a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
7506a97b51b8SMatthew G. Knepley         /* Old hybrid faces stay the same */
7507a97b51b8SMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
7508a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
7509a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
7510a97b51b8SMatthew G. Knepley         ++m;
7511a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
7512a97b51b8SMatthew G. Knepley         /* Old interior cells add new cells, interior faces, and vertex */
7513a97b51b8SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
7514a97b51b8SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
7515a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
7516a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
7517a97b51b8SMatthew G. Knepley         }
7518a97b51b8SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
7519a97b51b8SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*4     + r;
7520a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r;
7521a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
7522a97b51b8SMatthew G. Knepley         }
7523add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)               + (fMax                              - fStart)     + (p  - cStart);
7524add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0]  + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]);
7525add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
7526add09238SMatthew G. Knepley         ++m;
7527a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
7528a97b51b8SMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
7529a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
7530a97b51b8SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
7531a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
7532a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
7533a97b51b8SMatthew G. Knepley         }
7534a97b51b8SMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*4     + (p  - cMax);
7535a97b51b8SMatthew 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]);
7536a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
7537a97b51b8SMatthew G. Knepley         ++m;
7538a97b51b8SMatthew G. Knepley       }
7539a97b51b8SMatthew G. Knepley       break;
75409b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_3D:
75419b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_3D:
75426ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
75436ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
75446ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
75456ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
75466ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
75476ce3c06aSMatthew G. Knepley         ++m;
75486ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
75496ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
75506ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
75516ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
75526ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
75536ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
75546ce3c06aSMatthew G. Knepley         }
75556ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
75566ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
75576ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
75586ce3c06aSMatthew G. Knepley         ++m;
75596ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
75606ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
75616ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (p  - eMax);
75627d5cd7d5SMatthew 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]);
75636ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
75646ce3c06aSMatthew G. Knepley         ++m;
75656ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
75666ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
75676ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
75686ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
75696ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
75706ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
75716ce3c06aSMatthew G. Knepley         }
75726ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
75736ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*3     + r;
75746ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r;
75756ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
75766ce3c06aSMatthew G. Knepley         }
75776ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
75786ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
75796ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
7580899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (p  - fMax)*2                              + r;
7581899f98d0SMatthew 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;
75826ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
75836ce3c06aSMatthew G. Knepley         }
75847d5cd7d5SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (eEnd                                    - eMax)                        + (p  - fMax);
75857d5cd7d5SMatthew 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]);
75866ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
758709b1338fSMatthew G. Knepley         ++m;
75886ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
75896ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
75906ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
75916ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
75926ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
75936ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
75946ce3c06aSMatthew G. Knepley         }
75956ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
75966ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*8     + r;
75976ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r;
75986ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
75996ce3c06aSMatthew G. Knepley         }
7600c7c54c77SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (p  - cStart)*1     + 0;
7601c7c54c77SMatthew 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;
76026ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
760309b1338fSMatthew G. Knepley         ++m;
76046ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
76056ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
76066ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
76076ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
76086ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
76096ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
76106ce3c06aSMatthew G. Knepley         }
76116ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
7612899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (fEnd                                          - fMax)*2                              + (p  - cMax)*3                            + r;
7613899f98d0SMatthew 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;
76146ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
76156ce3c06aSMatthew G. Knepley         }
76166ce3c06aSMatthew G. Knepley       }
76176ce3c06aSMatthew G. Knepley       break;
7618e5337592SStefano Zampini     case REFINER_SIMPLEX_TO_HEX_3D:
7619e5337592SStefano Zampini       if ((p >= vStart) && (p < vEnd)) {
7620e5337592SStefano Zampini         /* Interior vertices stay the same */
7621e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (p  - vStart);
7622e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
7623e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7624e5337592SStefano Zampini         ++m;
7625e5337592SStefano Zampini       } else if ((p >= eStart) && (p < eEnd)) {
7626e5337592SStefano Zampini         /* Interior edges add new edges and vertex */
7627e5337592SStefano Zampini         for (r = 0; r < 2; ++r, ++m) {
7628e5337592SStefano Zampini           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
7629e5337592SStefano Zampini           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
7630e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7631e5337592SStefano Zampini         }
7632e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
7633e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
7634e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7635e5337592SStefano Zampini         ++m;
7636e5337592SStefano Zampini       } else if ((p >= fStart) && (p < fEnd)) {
7637e5337592SStefano Zampini         /* Interior faces add new faces, edges and a vertex */
7638e5337592SStefano Zampini         for (r = 0; r < 3; ++r, ++m) {
7639e5337592SStefano Zampini           localPointsNew[m]        = fStartNew     + (p  - fStart)*3     + r;
7640e5337592SStefano Zampini           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*3 + r;
7641e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7642e5337592SStefano Zampini         }
7643e5337592SStefano Zampini         for (r = 0; r < 3; ++r, ++m) {
7644e5337592SStefano Zampini           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2                + (p  - fStart)*3     + r;
7645e5337592SStefano Zampini           remotePointsNew[m].index = reStartNew[n] + (rdepthSizeOld[n*(depth+1)+1])*2 + (rp - rfStart[n])*3 + r;
7646e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7647e5337592SStefano Zampini         }
7648e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eEnd - eStart)              + (p - fStart);
7649e5337592SStefano Zampini         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]);
7650e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7651e5337592SStefano Zampini         ++m;
7652e5337592SStefano Zampini       } else if ((p >= cStart) && (p < cEnd)) {
7653e5337592SStefano Zampini         /* Interior cells add new cells, faces, edges, and a vertex */
7654e5337592SStefano Zampini         for (r = 0; r < 4; ++r, ++m) {
7655e5337592SStefano Zampini           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
7656e5337592SStefano Zampini           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
7657e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7658e5337592SStefano Zampini         }
7659e5337592SStefano Zampini         for (r = 0; r < 6; ++r, ++m) {
7660e5337592SStefano Zampini           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*3                    + (p  - cStart)*6     + r;
7661e5337592SStefano Zampini           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*6 + r;
7662e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7663e5337592SStefano Zampini         }
7664e5337592SStefano Zampini         for (r = 0; r < 4; ++r, ++m) {
7665e5337592SStefano Zampini           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (fEnd - fStart)*3                    + (p  - cStart)*4 + r;
7666e5337592SStefano Zampini           remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*4 + r;
7667e5337592SStefano Zampini           remotePointsNew[m].rank  = rrank;
7668e5337592SStefano Zampini         }
7669e5337592SStefano Zampini         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eEnd - eStart)              + (fEnd - fStart)                    + (p - cStart);
7670e5337592SStefano 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]);
7671e5337592SStefano Zampini         remotePointsNew[m].rank  = rrank;
7672e5337592SStefano Zampini         ++m;
7673e5337592SStefano Zampini       }
7674e5337592SStefano Zampini       break;
76759b1a0e7fSLawrence Mitchell     case REFINER_HEX_3D:
76769b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_3D:
767727fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
767827fcede3SMatthew G. Knepley         /* Interior vertices stay the same */
767927fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
768027fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
768127fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
768227fcede3SMatthew G. Knepley         ++m;
768327fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
768427fcede3SMatthew G. Knepley         /* Interior edges add new edges and vertex */
768527fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
768627fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
768727fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
768827fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
768927fcede3SMatthew G. Knepley         }
769027fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
769127fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
769227fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
769327fcede3SMatthew G. Knepley         ++m;
769427fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
769527fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
769627fcede3SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (p  - eMax);
7697d2701f60SMatthew 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]);
769827fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
769927fcede3SMatthew G. Knepley         ++m;
770027fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
770127fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
770227fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
770327fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
770427fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
770527fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
770627fcede3SMatthew G. Knepley         }
770727fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
770827fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*4     + r;
770927fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r;
771027fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
771127fcede3SMatthew G. Knepley         }
771227fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eMax                        - eStart)     + (p  - fStart);
771327fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]);
771427fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
771527fcede3SMatthew G. Knepley         ++m;
771627fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
771727fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
771827fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
7719d2701f60SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*12     + (p  - fMax)*2                              + r;
7720d2701f60SMatthew 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;
772127fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
772227fcede3SMatthew G. Knepley         }
7723d2701f60SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (eEnd                                    - eMax)                        + (p  - fMax);
7724d2701f60SMatthew 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]);
772527fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
772627fcede3SMatthew G. Knepley         ++m;
772727fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
772827fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
772927fcede3SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
773027fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
773127fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
773227fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
773327fcede3SMatthew G. Knepley         }
773427fcede3SMatthew G. Knepley         for (r = 0; r < 12; ++r, ++m) {
773527fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*12     + r;
773627fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r;
773727fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
773827fcede3SMatthew G. Knepley         }
773927fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r, ++m) {
774027fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (p  - cStart)*6     + r;
774127fcede3SMatthew 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;
774227fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
774327fcede3SMatthew G. Knepley         }
774427fcede3SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
774527fcede3SMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (eMax                        - eStart)     + (fMax                              - fStart)     + (p  - cStart)     + r;
774627fcede3SMatthew 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;
774727fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
774827fcede3SMatthew G. Knepley         }
774927fcede3SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
775027fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
775127fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
775227fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
775327fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
775427fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
775527fcede3SMatthew G. Knepley         }
775627fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
7757d2701f60SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*12     + (fEnd                                          - fMax)*2                              + (p  - cMax)*4                            + r;
7758d2701f60SMatthew 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;
775927fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
776027fcede3SMatthew G. Knepley         }
7761d2701f60SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (eEnd                                    - eMax)                        + (fEnd                                          - fMax)                              + (p  - cMax);
7762d2701f60SMatthew 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]);
776327fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
776427fcede3SMatthew G. Knepley         ++m;
776527fcede3SMatthew G. Knepley       }
776627fcede3SMatthew G. Knepley       break;
776775d3a19aSMatthew G. Knepley     default:
776875d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
776975d3a19aSMatthew G. Knepley     }
777075d3a19aSMatthew G. Knepley   }
777109b1338fSMatthew G. Knepley   if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew);
777275d3a19aSMatthew G. Knepley   ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr);
777375d3a19aSMatthew G. Knepley   ierr = ISDestroy(&processRanks);CHKERRQ(ierr);
7774ba3c3d50SMatthew G. Knepley   {
7775ba3c3d50SMatthew G. Knepley     PetscSFNode *rp, *rtmp;
7776ba3c3d50SMatthew G. Knepley     PetscInt    *lp, *idx, *ltmp, i;
7777ba3c3d50SMatthew G. Knepley 
7778ba3c3d50SMatthew G. Knepley     /* SF needs sorted leaves to correct calculate Gather */
7779ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr);
7780ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr);
7781ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr);
7782c7c54c77SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
7783c7c54c77SMatthew 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);
7784c7c54c77SMatthew G. Knepley       idx[i] = i;
7785c7c54c77SMatthew G. Knepley     }
7786ba3c3d50SMatthew G. Knepley     ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr);
7787ba3c3d50SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
7788ba3c3d50SMatthew G. Knepley       lp[i] = localPointsNew[idx[i]];
7789ba3c3d50SMatthew G. Knepley       rp[i] = remotePointsNew[idx[i]];
7790ba3c3d50SMatthew G. Knepley     }
7791ba3c3d50SMatthew G. Knepley     ltmp            = localPointsNew;
7792ba3c3d50SMatthew G. Knepley     localPointsNew  = lp;
7793ba3c3d50SMatthew G. Knepley     rtmp            = remotePointsNew;
7794ba3c3d50SMatthew G. Knepley     remotePointsNew = rp;
7795ba3c3d50SMatthew G. Knepley     ierr = PetscFree(idx);CHKERRQ(ierr);
7796ba3c3d50SMatthew G. Knepley     ierr = PetscFree(ltmp);CHKERRQ(ierr);
7797ba3c3d50SMatthew G. Knepley     ierr = PetscFree(rtmp);CHKERRQ(ierr);
7798ba3c3d50SMatthew G. Knepley   }
779975d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
780075d3a19aSMatthew G. Knepley   ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr);
780106a0ba2dSMatthew G. Knepley   ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr);
780275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
780375d3a19aSMatthew G. Knepley }
780475d3a19aSMatthew G. Knepley 
780586150812SJed Brown static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
780675d3a19aSMatthew G. Knepley {
780775d3a19aSMatthew G. Knepley   PetscInt       numLabels, l;
78087ba685a0SMatthew G. Knepley   PetscInt       depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r;
78097ba685a0SMatthew G. Knepley   PetscInt       cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
781075d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
781175d3a19aSMatthew G. Knepley 
781275d3a19aSMatthew G. Knepley   PetscFunctionBegin;
781375d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
781475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
781575d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
781675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
7817d963de37SMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
78183478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
7819c58f1c22SToby Isaac   ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr);
782075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
782175d3a19aSMatthew G. Knepley   switch (refiner) {
78229b1a0e7fSLawrence Mitchell   case REFINER_NOOP:
78230314a74cSLawrence Mitchell   case REFINER_SIMPLEX_1D:
78249b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
7825e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_2D:
78269b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
78279b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
78289b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
7829e5337592SStefano Zampini   case REFINER_SIMPLEX_TO_HEX_3D:
78309b1a0e7fSLawrence Mitchell     break;
78319b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
78329b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
783358b8852aSMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
78349b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
78359b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
783675d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
783775d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
78381e317b1dSMatthew G. Knepley     break;
78399b1a0e7fSLawrence Mitchell   default:
78409b1a0e7fSLawrence Mitchell     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
784175d3a19aSMatthew G. Knepley   }
784275d3a19aSMatthew G. Knepley   for (l = 0; l < numLabels; ++l) {
784375d3a19aSMatthew G. Knepley     DMLabel         label, labelNew;
784475d3a19aSMatthew G. Knepley     const char     *lname;
784575d3a19aSMatthew G. Knepley     PetscBool       isDepth;
784675d3a19aSMatthew G. Knepley     IS              valueIS;
784775d3a19aSMatthew G. Knepley     const PetscInt *values;
78485aa44df4SToby Isaac     PetscInt        defVal;
784975d3a19aSMatthew G. Knepley     PetscInt        numValues, val;
785075d3a19aSMatthew G. Knepley 
7851c58f1c22SToby Isaac     ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr);
785275d3a19aSMatthew G. Knepley     ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr);
785375d3a19aSMatthew G. Knepley     if (isDepth) continue;
7854c58f1c22SToby Isaac     ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr);
7855c58f1c22SToby Isaac     ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr);
7856c58f1c22SToby Isaac     ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr);
78575aa44df4SToby Isaac     ierr = DMLabelGetDefaultValue(label,&defVal);CHKERRQ(ierr);
78585aa44df4SToby Isaac     ierr = DMLabelSetDefaultValue(labelNew,defVal);CHKERRQ(ierr);
785975d3a19aSMatthew G. Knepley     ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr);
786075d3a19aSMatthew G. Knepley     ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr);
786175d3a19aSMatthew G. Knepley     ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr);
786275d3a19aSMatthew G. Knepley     for (val = 0; val < numValues; ++val) {
786375d3a19aSMatthew G. Knepley       IS              pointIS;
786475d3a19aSMatthew G. Knepley       const PetscInt *points;
786575d3a19aSMatthew G. Knepley       PetscInt        numPoints, n;
786675d3a19aSMatthew G. Knepley 
786775d3a19aSMatthew G. Knepley       ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr);
786875d3a19aSMatthew G. Knepley       ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);
786975d3a19aSMatthew G. Knepley       ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr);
78702bc5314cSMichael Lange       /* Ensure refined label is created with same number of strata as
78712bc5314cSMichael Lange        * original (even if no entries here). */
7872ad8374ffSToby Isaac       ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr);
787375d3a19aSMatthew G. Knepley       for (n = 0; n < numPoints; ++n) {
787475d3a19aSMatthew G. Knepley         const PetscInt p = points[n];
787575d3a19aSMatthew G. Knepley         switch (refiner) {
78760314a74cSLawrence Mitchell         case REFINER_SIMPLEX_1D:
78770314a74cSLawrence Mitchell           if ((p >= vStart) && (p < vEnd)) {
78780314a74cSLawrence Mitchell             /* Old vertices stay the same */
78790314a74cSLawrence Mitchell             newp = vStartNew + (p - vStart);
78800314a74cSLawrence Mitchell             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
78810314a74cSLawrence Mitchell           } else if ((p >= cStart) && (p < cEnd)) {
78820314a74cSLawrence Mitchell             /* Old cells add new cells and vertex */
78830314a74cSLawrence Mitchell             newp = vStartNew + (vEnd - vStart) + (p - cStart);
78840314a74cSLawrence Mitchell             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
78850314a74cSLawrence Mitchell             for (r = 0; r < 2; ++r) {
78860314a74cSLawrence Mitchell               newp = cStartNew + (p - cStart)*2 + r;
78870314a74cSLawrence Mitchell               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
78880314a74cSLawrence Mitchell             }
78890314a74cSLawrence Mitchell           }
78900314a74cSLawrence Mitchell           break;
78919b1a0e7fSLawrence Mitchell         case REFINER_SIMPLEX_2D:
789275d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
789375d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
789475d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
789575d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
789675d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
789775d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
789875d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
789975d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
790075d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
790175d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
790275d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
790375d3a19aSMatthew G. Knepley             }
790475d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
790575d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces */
790675d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
790775d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
790875d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
790975d3a19aSMatthew G. Knepley             }
791075d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
791175d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
791275d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
791375d3a19aSMatthew G. Knepley             }
791475d3a19aSMatthew G. Knepley           }
791575d3a19aSMatthew G. Knepley           break;
7916e5337592SStefano Zampini         case REFINER_SIMPLEX_TO_HEX_2D:
7917e5337592SStefano Zampini           if ((p >= vStart) && (p < vEnd)) {
7918e5337592SStefano Zampini             /* Old vertices stay the same */
7919e5337592SStefano Zampini             newp = vStartNew + (p - vStart);
7920e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7921e5337592SStefano Zampini           } else if ((p >= fStart) && (p < fEnd)) {
7922e5337592SStefano Zampini             /* Old faces add new faces and vertex */
7923e5337592SStefano Zampini             newp = vStartNew + (vEnd - vStart) + (p - fStart);
7924e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7925e5337592SStefano Zampini             for (r = 0; r < 2; ++r) {
7926e5337592SStefano Zampini               newp = fStartNew + (p - fStart)*2 + r;
7927e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7928e5337592SStefano Zampini             }
7929e5337592SStefano Zampini           } else if ((p >= cStart) && (p < cEnd)) {
7930e5337592SStefano Zampini             /* Old cells add new cells, interior faces, and a vertex */
7931e5337592SStefano Zampini             for (r = 0; r < 3; ++r) {
7932e5337592SStefano Zampini               newp = cStartNew + (p - cStart)*3 + r;
7933e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7934e5337592SStefano Zampini             }
7935e5337592SStefano Zampini             for (r = 0; r < 3; ++r) {
7936e5337592SStefano Zampini               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
7937e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7938e5337592SStefano Zampini             }
7939e5337592SStefano Zampini             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p;
7940e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
7941e5337592SStefano Zampini           }
7942e5337592SStefano Zampini           break;
79439b1a0e7fSLawrence Mitchell         case REFINER_HEX_2D:
794475d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
794575d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
794675d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
794775d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
794875d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
794975d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
795075d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
795175d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
795275d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
795375d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
795475d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
795575d3a19aSMatthew G. Knepley             }
795675d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
795775d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces and vertex */
795875d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
795975d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
796075d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
796175d3a19aSMatthew G. Knepley             }
796275d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
796375d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
796475d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
796575d3a19aSMatthew G. Knepley             }
796675d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
796775d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
796875d3a19aSMatthew G. Knepley           }
796975d3a19aSMatthew G. Knepley           break;
79709b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_SIMPLEX_2D:
797175d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
797275d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
797375d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
797475d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
797575d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
797675d3a19aSMatthew G. Knepley             /* Old interior faces add new faces and vertex */
797775d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
797875d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
797975d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
798075d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
798175d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
798275d3a19aSMatthew G. Knepley             }
798375d3a19aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
798475d3a19aSMatthew G. Knepley             /* Old hybrid faces stay the same */
798575d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
798675d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
798775d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
798875d3a19aSMatthew G. Knepley             /* Old interior cells add new cells and interior faces */
798975d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
799075d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
799175d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
799275d3a19aSMatthew G. Knepley             }
799375d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
799475d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
799575d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
799675d3a19aSMatthew G. Knepley             }
799775d3a19aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
799875d3a19aSMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
799975d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
800075d3a19aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
800175d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
800275d3a19aSMatthew G. Knepley             }
800375d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
800475d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
800575d3a19aSMatthew G. Knepley           }
800675d3a19aSMatthew G. Knepley           break;
80079b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_HEX_2D:
8008a97b51b8SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
8009a97b51b8SMatthew G. Knepley             /* Old vertices stay the same */
8010a97b51b8SMatthew G. Knepley             newp = vStartNew + (p - vStart);
8011a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8012a97b51b8SMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
8013a97b51b8SMatthew G. Knepley             /* Old interior faces add new faces and vertex */
8014a97b51b8SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
8015a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8016a97b51b8SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
8017a97b51b8SMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
8018a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8019a97b51b8SMatthew G. Knepley             }
8020a97b51b8SMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
8021a97b51b8SMatthew G. Knepley             /* Old hybrid faces stay the same */
8022a97b51b8SMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
8023a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8024a97b51b8SMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
8025a97b51b8SMatthew G. Knepley             /* Old interior cells add new cells, interior faces, and vertex */
8026a97b51b8SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
8027a97b51b8SMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
8028a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8029a97b51b8SMatthew G. Knepley             }
8030a97b51b8SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
8031a97b51b8SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
8032a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8033a97b51b8SMatthew G. Knepley             }
8034a97b51b8SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
8035a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8036a97b51b8SMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
8037a97b51b8SMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
8038a97b51b8SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
8039a97b51b8SMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
8040a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8041a97b51b8SMatthew G. Knepley             }
8042a97b51b8SMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax);
8043a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8044a97b51b8SMatthew G. Knepley           }
8045a97b51b8SMatthew G. Knepley           break;
80469b1a0e7fSLawrence Mitchell         case REFINER_SIMPLEX_3D:
8047b5da9499SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
8048b5da9499SMatthew G. Knepley             /* Old vertices stay the same */
8049b5da9499SMatthew G. Knepley             newp = vStartNew + (p - vStart);
8050b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8051b5da9499SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
8052b5da9499SMatthew G. Knepley             /* Old edges add new edges and vertex */
8053b5da9499SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
8054b5da9499SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
8055b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8056b5da9499SMatthew G. Knepley             }
8057b5da9499SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
8058b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8059b5da9499SMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
8060b5da9499SMatthew G. Knepley             /* Old faces add new faces and edges */
8061b5da9499SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
8062b5da9499SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
8063b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8064b5da9499SMatthew G. Knepley             }
8065b5da9499SMatthew G. Knepley             for (r = 0; r < 3; ++r) {
8066b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
8067b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8068b5da9499SMatthew G. Knepley             }
8069b5da9499SMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
8070b5da9499SMatthew G. Knepley             /* Old cells add new cells and interior faces and edges */
8071b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
8072b5da9499SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
8073b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8074b5da9499SMatthew G. Knepley             }
8075b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
8076b5da9499SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r;
8077b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8078b5da9499SMatthew G. Knepley             }
8079b5da9499SMatthew G. Knepley             for (r = 0; r < 1; ++r) {
8080b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r;
8081b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8082b5da9499SMatthew G. Knepley             }
8083b5da9499SMatthew G. Knepley           }
8084b5da9499SMatthew G. Knepley           break;
8085e5337592SStefano Zampini         case REFINER_SIMPLEX_TO_HEX_3D:
8086e5337592SStefano Zampini           if ((p >= vStart) && (p < vEnd)) {
8087e5337592SStefano Zampini             /* Old vertices stay the same */
8088e5337592SStefano Zampini             newp = vStartNew + (p - vStart);
8089e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8090e5337592SStefano Zampini           } else if ((p >= eStart) && (p < eEnd)) {
8091e5337592SStefano Zampini             /* Old edges add new edges and vertex */
8092e5337592SStefano Zampini             for (r = 0; r < 2; ++r) {
8093e5337592SStefano Zampini               newp = eStartNew + (p - eStart)*2 + r;
8094e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8095e5337592SStefano Zampini             }
8096e5337592SStefano Zampini             newp = vStartNew + (vEnd - vStart) + (p - eStart);
8097e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8098e5337592SStefano Zampini           } else if ((p >= fStart) && (p < fEnd)) {
8099e5337592SStefano Zampini             /* Old faces add new faces, edges and a vertex */
8100e5337592SStefano Zampini             for (r = 0; r < 3; ++r) {
8101e5337592SStefano Zampini               newp = fStartNew + (p - fStart)*3 + r;
8102e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8103e5337592SStefano Zampini             }
8104e5337592SStefano Zampini             for (r = 0; r < 3; ++r) {
8105e5337592SStefano Zampini               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
8106e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8107e5337592SStefano Zampini             }
8108e5337592SStefano Zampini           } else if ((p >= cStart) && (p < cEnd)) {
8109e5337592SStefano Zampini             /* Old cells add new cells and interior faces and edges and a vertex */
8110e5337592SStefano Zampini             for (r = 0; r < 4; ++r) {
8111e5337592SStefano Zampini               newp = cStartNew + (p - cStart)*4 + r;
8112e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8113e5337592SStefano Zampini             }
8114e5337592SStefano Zampini             for (r = 0; r < 6; ++r) {
8115e5337592SStefano Zampini               newp = fStartNew + (fEnd - fStart)*3 + (p - cStart)*6 + r;
8116e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8117e5337592SStefano Zampini             }
8118e5337592SStefano Zampini             for (r = 0; r < 4; ++r) {
8119e5337592SStefano Zampini               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*4 + r;
8120e5337592SStefano Zampini               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8121e5337592SStefano Zampini             }
8122e5337592SStefano Zampini             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + p - cStart;
8123e5337592SStefano Zampini             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
8124e5337592SStefano Zampini           }
8125e5337592SStefano Zampini           break;
81269b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_SIMPLEX_3D:
81276ce3c06aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
81286ce3c06aSMatthew G. Knepley             /* Interior vertices stay the same */
81296ce3c06aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
81306ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
81316ce3c06aSMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
81326ce3c06aSMatthew G. Knepley             /* Interior edges add new edges and vertex */
81336ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
81346ce3c06aSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
81356ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
81366ce3c06aSMatthew G. Knepley             }
81376ce3c06aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
81386ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
81396ce3c06aSMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
81406ce3c06aSMatthew G. Knepley             /* Hybrid edges stay the same */
81416ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
81426ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
81436ce3c06aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
81446ce3c06aSMatthew G. Knepley             /* Interior faces add new faces and edges */
81456ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
81466ce3c06aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
81476ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
81486ce3c06aSMatthew G. Knepley             }
81496ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
81506ce3c06aSMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
81516ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
81526ce3c06aSMatthew G. Knepley             }
81536ce3c06aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
81546ce3c06aSMatthew G. Knepley             /* Hybrid faces add new faces and edges */
81556ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
81566ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
81576ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
81586ce3c06aSMatthew G. Knepley             }
81596ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax);
81606ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
81616ce3c06aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
81626ce3c06aSMatthew G. Knepley             /* Interior cells add new cells, faces, and edges */
81636ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
81646ce3c06aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
81656ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
81666ce3c06aSMatthew G. Knepley             }
81676ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
81686ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
81696ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
81706ce3c06aSMatthew G. Knepley             }
81716ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart);
81726ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
817358b8852aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
81746ce3c06aSMatthew G. Knepley             /* Hybrid cells add new cells and faces */
81756ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
81766ce3c06aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
81776ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
81786ce3c06aSMatthew G. Knepley             }
81796ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
81806ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
81816ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
81826ce3c06aSMatthew G. Knepley             }
81836ce3c06aSMatthew G. Knepley           }
81846ce3c06aSMatthew G. Knepley           break;
81859b1a0e7fSLawrence Mitchell         case REFINER_HEX_3D:
81862eabf88fSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
81872eabf88fSMatthew G. Knepley             /* Old vertices stay the same */
81882eabf88fSMatthew G. Knepley             newp = vStartNew + (p - vStart);
81892eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
819019d7d790SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
81912eabf88fSMatthew G. Knepley             /* Old edges add new edges and vertex */
81922eabf88fSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
81932eabf88fSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
81942eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
81952eabf88fSMatthew G. Knepley             }
81962eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
81972eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
81982eabf88fSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
81992eabf88fSMatthew G. Knepley             /* Old faces add new faces, edges, and vertex */
82002eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
82012eabf88fSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
82022eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
82032eabf88fSMatthew G. Knepley             }
82042eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
82052eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r;
82062eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
82072eabf88fSMatthew G. Knepley             }
82082eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart);
82092eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
82102eabf88fSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
82112eabf88fSMatthew G. Knepley             /* Old cells add new cells, faces, edges, and vertex */
82122eabf88fSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
82132eabf88fSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
82142eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
82152eabf88fSMatthew G. Knepley             }
82162eabf88fSMatthew G. Knepley             for (r = 0; r < 12; ++r) {
82172eabf88fSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r;
82182eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
82192eabf88fSMatthew G. Knepley             }
82202eabf88fSMatthew G. Knepley             for (r = 0; r < 6; ++r) {
82212eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r;
82222eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
82232eabf88fSMatthew G. Knepley             }
82242eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart);
82252eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
82262eabf88fSMatthew G. Knepley           }
82272eabf88fSMatthew G. Knepley           break;
82289b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_HEX_3D:
822927fcede3SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
823027fcede3SMatthew G. Knepley             /* Interior vertices stay the same */
823127fcede3SMatthew G. Knepley             newp = vStartNew + (p - vStart);
823227fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
823327fcede3SMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
823427fcede3SMatthew G. Knepley             /* Interior edges add new edges and vertex */
823527fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
823627fcede3SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
823727fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
823827fcede3SMatthew G. Knepley             }
823927fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
824027fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
824127fcede3SMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
824227fcede3SMatthew G. Knepley             /* Hybrid edges stay the same */
824327fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax);
824427fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
824527fcede3SMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
824627fcede3SMatthew G. Knepley             /* Interior faces add new faces, edges, and vertex */
824727fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
824827fcede3SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
824927fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
825027fcede3SMatthew G. Knepley             }
825127fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
825227fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r;
825327fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
825427fcede3SMatthew G. Knepley             }
825527fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
825627fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
825727fcede3SMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
825827fcede3SMatthew G. Knepley             /* Hybrid faces add new faces and edges */
825927fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
826027fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r;
826127fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
826227fcede3SMatthew G. Knepley             }
826327fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax);
826427fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
826527fcede3SMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
826627fcede3SMatthew G. Knepley             /* Interior cells add new cells, faces, edges, and vertex */
826727fcede3SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
826827fcede3SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
826927fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
827027fcede3SMatthew G. Knepley             }
827127fcede3SMatthew G. Knepley             for (r = 0; r < 12; ++r) {
827227fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r;
827327fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
827427fcede3SMatthew G. Knepley             }
827527fcede3SMatthew G. Knepley             for (r = 0; r < 6; ++r) {
827627fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r;
827727fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
827827fcede3SMatthew G. Knepley             }
827927fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart);
828027fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
828127fcede3SMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
828227fcede3SMatthew G. Knepley             /* Hybrid cells add new cells, faces, and edges */
828327fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
828427fcede3SMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
828527fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
828627fcede3SMatthew G. Knepley             }
828727fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
828827fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r;
828927fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
829027fcede3SMatthew G. Knepley             }
829127fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax);
829227fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
829327fcede3SMatthew G. Knepley           }
829427fcede3SMatthew G. Knepley           break;
829575d3a19aSMatthew G. Knepley         default:
829675d3a19aSMatthew G. Knepley           SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
829775d3a19aSMatthew G. Knepley         }
829875d3a19aSMatthew G. Knepley       }
829975d3a19aSMatthew G. Knepley       ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr);
830075d3a19aSMatthew G. Knepley       ierr = ISDestroy(&pointIS);CHKERRQ(ierr);
830175d3a19aSMatthew G. Knepley     }
830275d3a19aSMatthew G. Knepley     ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr);
830375d3a19aSMatthew G. Knepley     ierr = ISDestroy(&valueIS);CHKERRQ(ierr);
830475d3a19aSMatthew G. Knepley     if (0) {
830575d3a19aSMatthew G. Knepley       ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
830675d3a19aSMatthew G. Knepley     }
830775d3a19aSMatthew G. Knepley   }
830875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
830975d3a19aSMatthew G. Knepley }
831075d3a19aSMatthew G. Knepley 
831175d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */
8312509c9b89SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined)
831375d3a19aSMatthew G. Knepley {
831475d3a19aSMatthew G. Knepley   DM             rdm;
831575d3a19aSMatthew G. Knepley   PetscInt      *depthSize;
831675d3a19aSMatthew G. Knepley   PetscInt       dim, depth = 0, d, pStart = 0, pEnd = 0;
831775d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
831875d3a19aSMatthew G. Knepley 
831975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
832075d3a19aSMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr);
832175d3a19aSMatthew G. Knepley   ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr);
8322c73cfb54SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
8323c73cfb54SMatthew G. Knepley   ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr);
832475d3a19aSMatthew G. Knepley   /* Calculate number of new points of each depth */
832575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
83261e573d11SMatthew G. Knepley   if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement");
8327854ce69bSBarry Smith   ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr);
832875d3a19aSMatthew G. Knepley   ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr);
832975d3a19aSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
833075d3a19aSMatthew G. Knepley   /* Step 1: Set chart */
833175d3a19aSMatthew G. Knepley   for (d = 0; d <= depth; ++d) pEnd += depthSize[d];
833275d3a19aSMatthew G. Knepley   ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr);
83336d7373e8SToby Isaac   /* Step 2: Set cone/support sizes (automatically stratifies) */
833475d3a19aSMatthew G. Knepley   ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
833575d3a19aSMatthew G. Knepley   /* Step 3: Setup refined DM */
833675d3a19aSMatthew G. Knepley   ierr = DMSetUp(rdm);CHKERRQ(ierr);
83376d7373e8SToby Isaac   /* Step 4: Set cones and supports (automatically symmetrizes) */
833875d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
83396d7373e8SToby Isaac   /* Step 5: Create pointSF */
834075d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
83416d7373e8SToby Isaac   /* Step 6: Create labels */
834275d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
83436d7373e8SToby Isaac   /* Step 7: Set coordinates */
834490b157c4SStefano Zampini   ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
834575d3a19aSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
834675d3a19aSMatthew G. Knepley 
834775d3a19aSMatthew G. Knepley   *dmRefined = rdm;
834875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
834975d3a19aSMatthew G. Knepley }
835075d3a19aSMatthew G. Knepley 
83512389894bSMatthew G. Knepley /*@
83522389894bSMatthew G. Knepley   DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data
83532389894bSMatthew G. Knepley 
83542389894bSMatthew G. Knepley   Input Parameter:
83552389894bSMatthew G. Knepley . dm - The coarse DM
83562389894bSMatthew G. Knepley 
83572389894bSMatthew G. Knepley   Output Parameter:
83582389894bSMatthew G. Knepley . fpointIS - The IS of all the fine points which exist in the original coarse mesh
83592389894bSMatthew G. Knepley 
83602389894bSMatthew G. Knepley   Level: developer
83612389894bSMatthew G. Knepley 
83622389894bSMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS()
83632389894bSMatthew G. Knepley @*/
83642389894bSMatthew G. Knepley PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS)
83652389894bSMatthew G. Knepley {
83662389894bSMatthew G. Knepley   CellRefiner    cellRefiner;
83672389894bSMatthew G. Knepley   PetscInt      *depthSize, *fpoints;
83682389894bSMatthew G. Knepley   PetscInt       cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
83692389894bSMatthew G. Knepley   PetscInt       depth, pStart, pEnd, p, vStart, vEnd, v;
83702389894bSMatthew G. Knepley   PetscErrorCode ierr;
83712389894bSMatthew G. Knepley 
83722389894bSMatthew G. Knepley   PetscFunctionBegin;
83732389894bSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
83742389894bSMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
83752389894bSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
83762389894bSMatthew G. Knepley   ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr);
8377854ce69bSBarry Smith   ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr);
83782389894bSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
83792389894bSMatthew G. Knepley   if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
83802389894bSMatthew G. Knepley   ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr);
83812389894bSMatthew G. Knepley   for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1;
83822389894bSMatthew G. Knepley   switch (cellRefiner) {
83836c0c04f5SMatthew G. Knepley   case REFINER_SIMPLEX_1D:
83846c0c04f5SMatthew G. Knepley   case REFINER_SIMPLEX_2D:
83856c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_SIMPLEX_2D:
83866c0c04f5SMatthew G. Knepley   case REFINER_HEX_2D:
83876c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_HEX_2D:
83886c0c04f5SMatthew G. Knepley   case REFINER_SIMPLEX_3D:
83896c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_SIMPLEX_3D:
83906c0c04f5SMatthew G. Knepley   case REFINER_HEX_3D:
83916c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_HEX_3D:
83922389894bSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart);
83932389894bSMatthew G. Knepley     break;
83942389894bSMatthew G. Knepley   default:
83952389894bSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", cellRefiner);
83962389894bSMatthew G. Knepley   }
83972389894bSMatthew G. Knepley   ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr);
83982389894bSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
83992389894bSMatthew G. Knepley   PetscFunctionReturn(0);
84002389894bSMatthew G. Knepley }
84012389894bSMatthew G. Knepley 
84020e2b6761SMatthew G. Knepley /*@
84030e2b6761SMatthew G. Knepley   DMPlexSetRefinementUniform - Set the flag for uniform refinement
84040e2b6761SMatthew G. Knepley 
84050e2b6761SMatthew G. Knepley   Input Parameters:
84060e2b6761SMatthew G. Knepley + dm - The DM
84070e2b6761SMatthew G. Knepley - refinementUniform - The flag for uniform refinement
84080e2b6761SMatthew G. Knepley 
84090e2b6761SMatthew G. Knepley   Level: developer
84100e2b6761SMatthew G. Knepley 
84110e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
84120e2b6761SMatthew G. Knepley @*/
841375d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
841475d3a19aSMatthew G. Knepley {
841575d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
841675d3a19aSMatthew G. Knepley 
841775d3a19aSMatthew G. Knepley   PetscFunctionBegin;
841875d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
841975d3a19aSMatthew G. Knepley   mesh->refinementUniform = refinementUniform;
842075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
842175d3a19aSMatthew G. Knepley }
842275d3a19aSMatthew G. Knepley 
84230e2b6761SMatthew G. Knepley /*@
84240e2b6761SMatthew G. Knepley   DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement
84250e2b6761SMatthew G. Knepley 
84260e2b6761SMatthew G. Knepley   Input Parameter:
84270e2b6761SMatthew G. Knepley . dm - The DM
84280e2b6761SMatthew G. Knepley 
84290e2b6761SMatthew G. Knepley   Output Parameter:
84300e2b6761SMatthew G. Knepley . refinementUniform - The flag for uniform refinement
84310e2b6761SMatthew G. Knepley 
84320e2b6761SMatthew G. Knepley   Level: developer
84330e2b6761SMatthew G. Knepley 
84340e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
84350e2b6761SMatthew G. Knepley @*/
843675d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
843775d3a19aSMatthew G. Knepley {
843875d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
843975d3a19aSMatthew G. Knepley 
844075d3a19aSMatthew G. Knepley   PetscFunctionBegin;
844175d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
844275d3a19aSMatthew G. Knepley   PetscValidPointer(refinementUniform,  2);
844375d3a19aSMatthew G. Knepley   *refinementUniform = mesh->refinementUniform;
844475d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
844575d3a19aSMatthew G. Knepley }
844675d3a19aSMatthew G. Knepley 
84470e2b6761SMatthew G. Knepley /*@
84480e2b6761SMatthew G. Knepley   DMPlexSetRefinementLimit - Set the maximum cell volume for refinement
84490e2b6761SMatthew G. Knepley 
84500e2b6761SMatthew G. Knepley   Input Parameters:
84510e2b6761SMatthew G. Knepley + dm - The DM
84520e2b6761SMatthew G. Knepley - refinementLimit - The maximum cell volume in the refined mesh
84530e2b6761SMatthew G. Knepley 
84540e2b6761SMatthew G. Knepley   Level: developer
84550e2b6761SMatthew G. Knepley 
84560e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
84570e2b6761SMatthew G. Knepley @*/
845875d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
845975d3a19aSMatthew G. Knepley {
846075d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
846175d3a19aSMatthew G. Knepley 
846275d3a19aSMatthew G. Knepley   PetscFunctionBegin;
846375d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
846475d3a19aSMatthew G. Knepley   mesh->refinementLimit = refinementLimit;
846575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
846675d3a19aSMatthew G. Knepley }
846775d3a19aSMatthew G. Knepley 
84680e2b6761SMatthew G. Knepley /*@
84690e2b6761SMatthew G. Knepley   DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement
84700e2b6761SMatthew G. Knepley 
84710e2b6761SMatthew G. Knepley   Input Parameter:
84720e2b6761SMatthew G. Knepley . dm - The DM
84730e2b6761SMatthew G. Knepley 
84740e2b6761SMatthew G. Knepley   Output Parameter:
84750e2b6761SMatthew G. Knepley . refinementLimit - The maximum cell volume in the refined mesh
84760e2b6761SMatthew G. Knepley 
84770e2b6761SMatthew G. Knepley   Level: developer
84780e2b6761SMatthew G. Knepley 
84790e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
84800e2b6761SMatthew G. Knepley @*/
848175d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
848275d3a19aSMatthew G. Knepley {
848375d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
848475d3a19aSMatthew G. Knepley 
848575d3a19aSMatthew G. Knepley   PetscFunctionBegin;
848675d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
848775d3a19aSMatthew G. Knepley   PetscValidPointer(refinementLimit,  2);
848875d3a19aSMatthew G. Knepley   /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
848975d3a19aSMatthew G. Knepley   *refinementLimit = mesh->refinementLimit;
849075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
849175d3a19aSMatthew G. Knepley }
849275d3a19aSMatthew G. Knepley 
8493b28003e6SMatthew G. Knepley /*@
8494b28003e6SMatthew G. Knepley   DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement
8495b28003e6SMatthew G. Knepley 
8496b28003e6SMatthew G. Knepley   Input Parameters:
8497b28003e6SMatthew G. Knepley + dm - The DM
8498b28003e6SMatthew G. Knepley - refinementFunc - Function giving the maximum cell volume in the refined mesh
8499b28003e6SMatthew G. Knepley 
8500b28003e6SMatthew G. Knepley   Note: The calling sequence is refinementFunc(coords, limit)
8501b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid
8502b28003e6SMatthew G. Knepley $ limit  - The maximum cell volume for a cell containing this point
8503b28003e6SMatthew G. Knepley 
8504b28003e6SMatthew G. Knepley   Level: developer
8505b28003e6SMatthew G. Knepley 
8506b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
8507b28003e6SMatthew G. Knepley @*/
8508b28003e6SMatthew G. Knepley PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *))
8509b28003e6SMatthew G. Knepley {
8510b28003e6SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
8511b28003e6SMatthew G. Knepley 
8512b28003e6SMatthew G. Knepley   PetscFunctionBegin;
8513b28003e6SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8514b28003e6SMatthew G. Knepley   mesh->refinementFunc = refinementFunc;
8515b28003e6SMatthew G. Knepley   PetscFunctionReturn(0);
8516b28003e6SMatthew G. Knepley }
8517b28003e6SMatthew G. Knepley 
8518b28003e6SMatthew G. Knepley /*@
8519b28003e6SMatthew G. Knepley   DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement
8520b28003e6SMatthew G. Knepley 
8521b28003e6SMatthew G. Knepley   Input Parameter:
8522b28003e6SMatthew G. Knepley . dm - The DM
8523b28003e6SMatthew G. Knepley 
8524b28003e6SMatthew G. Knepley   Output Parameter:
8525b28003e6SMatthew G. Knepley . refinementFunc - Function giving the maximum cell volume in the refined mesh
8526b28003e6SMatthew G. Knepley 
8527b28003e6SMatthew G. Knepley   Note: The calling sequence is refinementFunc(coords, limit)
8528b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid
8529b28003e6SMatthew G. Knepley $ limit  - The maximum cell volume for a cell containing this point
8530b28003e6SMatthew G. Knepley 
8531b28003e6SMatthew G. Knepley   Level: developer
8532b28003e6SMatthew G. Knepley 
8533b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
8534b28003e6SMatthew G. Knepley @*/
8535b28003e6SMatthew G. Knepley PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *))
8536b28003e6SMatthew G. Knepley {
8537b28003e6SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
8538b28003e6SMatthew G. Knepley 
8539b28003e6SMatthew G. Knepley   PetscFunctionBegin;
8540b28003e6SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8541b28003e6SMatthew G. Knepley   PetscValidPointer(refinementFunc,  2);
8542b28003e6SMatthew G. Knepley   *refinementFunc = mesh->refinementFunc;
8543b28003e6SMatthew G. Knepley   PetscFunctionReturn(0);
8544b28003e6SMatthew G. Knepley }
8545b28003e6SMatthew G. Knepley 
8546509c9b89SMatthew G. Knepley PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner)
854775d3a19aSMatthew G. Knepley {
85480f9259d6SMatthew G. Knepley   PetscInt       dim, cStart, cEnd, coneSize, cMax, fMax;
854975d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
855075d3a19aSMatthew G. Knepley 
855175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
8552c73cfb54SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
85533478d7aaSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
85549b1a0e7fSLawrence Mitchell   if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; PetscFunctionReturn(0);}
855575d3a19aSMatthew G. Knepley   ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr);
855689b38ed4SMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, NULL, NULL);CHKERRQ(ierr);
855775d3a19aSMatthew G. Knepley   switch (dim) {
85580314a74cSLawrence Mitchell   case 1:
85590314a74cSLawrence Mitchell     switch (coneSize) {
85600314a74cSLawrence Mitchell     case 2:
85610314a74cSLawrence Mitchell       *cellRefiner = REFINER_SIMPLEX_1D;
85620314a74cSLawrence Mitchell       break;
85630314a74cSLawrence Mitchell     default:
85640314a74cSLawrence Mitchell       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
85650314a74cSLawrence Mitchell     }
85660314a74cSLawrence Mitchell     break;
856775d3a19aSMatthew G. Knepley   case 2:
856875d3a19aSMatthew G. Knepley     switch (coneSize) {
856975d3a19aSMatthew G. Knepley     case 3:
85709b1a0e7fSLawrence Mitchell       if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_2D;
85719b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_SIMPLEX_2D;
857275d3a19aSMatthew G. Knepley       break;
857375d3a19aSMatthew G. Knepley     case 4:
857489b38ed4SMatthew G. Knepley       if (cMax >= 0 && fMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_2D;
85759b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_HEX_2D;
857675d3a19aSMatthew G. Knepley       break;
857775d3a19aSMatthew G. Knepley     default:
857875d3a19aSMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
857975d3a19aSMatthew G. Knepley     }
858075d3a19aSMatthew G. Knepley     break;
8581b5da9499SMatthew G. Knepley   case 3:
8582b5da9499SMatthew G. Knepley     switch (coneSize) {
8583b5da9499SMatthew G. Knepley     case 4:
85849b1a0e7fSLawrence Mitchell       if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D;
85859b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_SIMPLEX_3D;
8586b5da9499SMatthew G. Knepley       break;
85872eabf88fSMatthew G. Knepley     case 6:
85889b1a0e7fSLawrence Mitchell       if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_3D;
85899b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_HEX_3D;
85902eabf88fSMatthew G. Knepley       break;
8591b5da9499SMatthew G. Knepley     default:
8592b5da9499SMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
8593b5da9499SMatthew G. Knepley     }
8594b5da9499SMatthew G. Knepley     break;
859575d3a19aSMatthew G. Knepley   default:
859675d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim);
859775d3a19aSMatthew G. Knepley   }
859875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
859975d3a19aSMatthew G. Knepley }
86000d1cd5e0SMatthew G. Knepley 
86010d1cd5e0SMatthew G. Knepley PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined)
86020d1cd5e0SMatthew G. Knepley {
8603492b8470SStefano Zampini   PetscBool      isUniform;
86040d1cd5e0SMatthew G. Knepley   PetscErrorCode ierr;
86050d1cd5e0SMatthew G. Knepley 
86060d1cd5e0SMatthew G. Knepley   PetscFunctionBegin;
86070d1cd5e0SMatthew G. Knepley   ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr);
86080d1cd5e0SMatthew G. Knepley   if (isUniform) {
86090d1cd5e0SMatthew G. Knepley     CellRefiner cellRefiner;
8610492b8470SStefano Zampini     PetscBool   localized;
86110d1cd5e0SMatthew G. Knepley 
8612492b8470SStefano Zampini     ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr);
86130d1cd5e0SMatthew G. Knepley     ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr);
86140d1cd5e0SMatthew G. Knepley     ierr = DMPlexRefineUniform_Internal(dm, cellRefiner, dmRefined);CHKERRQ(ierr);
86150d1cd5e0SMatthew G. Knepley     ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr);
86160d1cd5e0SMatthew G. Knepley     if (localized) {ierr = DMLocalizeCoordinates(*dmRefined);CHKERRQ(ierr);}
86170d1cd5e0SMatthew G. Knepley   } else {
86180d1cd5e0SMatthew G. Knepley     ierr = DMPlexRefine_Internal(dm, NULL, dmRefined);CHKERRQ(ierr);
86190d1cd5e0SMatthew G. Knepley   }
86200d1cd5e0SMatthew G. Knepley   PetscFunctionReturn(0);
86210d1cd5e0SMatthew G. Knepley }
86220d1cd5e0SMatthew G. Knepley 
86230d1cd5e0SMatthew G. Knepley PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[])
86240d1cd5e0SMatthew G. Knepley {
86250d1cd5e0SMatthew G. Knepley   DM             cdm = dm;
86260d1cd5e0SMatthew G. Knepley   PetscInt       r;
86270d1cd5e0SMatthew G. Knepley   PetscBool      isUniform, localized;
86280d1cd5e0SMatthew G. Knepley   PetscErrorCode ierr;
86290d1cd5e0SMatthew G. Knepley 
86300d1cd5e0SMatthew G. Knepley   PetscFunctionBegin;
86310d1cd5e0SMatthew G. Knepley   ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr);
86320d1cd5e0SMatthew G. Knepley   ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr);
86330d1cd5e0SMatthew G. Knepley   if (isUniform) {
86340d1cd5e0SMatthew G. Knepley     for (r = 0; r < nlevels; ++r) {
86350d1cd5e0SMatthew G. Knepley       CellRefiner cellRefiner;
86360d1cd5e0SMatthew G. Knepley 
86370d1cd5e0SMatthew G. Knepley       ierr = DMPlexGetCellRefiner_Internal(cdm, &cellRefiner);CHKERRQ(ierr);
86380d1cd5e0SMatthew G. Knepley       ierr = DMPlexRefineUniform_Internal(cdm, cellRefiner, &dmRefined[r]);CHKERRQ(ierr);
86390d1cd5e0SMatthew G. Knepley       ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr);
86400d1cd5e0SMatthew G. Knepley       if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);}
86410d1cd5e0SMatthew G. Knepley       ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr);
86420d1cd5e0SMatthew G. Knepley       ierr = DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);CHKERRQ(ierr);
86430d1cd5e0SMatthew G. Knepley       cdm  = dmRefined[r];
86440d1cd5e0SMatthew G. Knepley     }
86450d1cd5e0SMatthew G. Knepley   } else {
86460d1cd5e0SMatthew G. Knepley     for (r = 0; r < nlevels; ++r) {
86470d1cd5e0SMatthew G. Knepley       ierr = DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);CHKERRQ(ierr);
86480d1cd5e0SMatthew G. Knepley       ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr);
86490d1cd5e0SMatthew G. Knepley       if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);}
86500d1cd5e0SMatthew G. Knepley       ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr);
86510d1cd5e0SMatthew G. Knepley       cdm  = dmRefined[r];
86520d1cd5e0SMatthew G. Knepley     }
86530d1cd5e0SMatthew G. Knepley   }
86540d1cd5e0SMatthew G. Knepley   PetscFunctionReturn(0);
86550d1cd5e0SMatthew G. Knepley }
8656