xref: /petsc/src/dm/impls/plex/plexrefine.c (revision 509c9b89ff00a5bbba0dab0bef0d2680448526ce)
175d3a19aSMatthew G. Knepley #include <petsc-private/dmpleximpl.h>   /*I      "petscdmplex.h"   I*/
275d3a19aSMatthew G. Knepley #include <petscsf.h>
375d3a19aSMatthew G. Knepley 
475d3a19aSMatthew G. Knepley #undef __FUNCT__
575d3a19aSMatthew G. Knepley #define __FUNCT__ "GetDepthStart_Private"
675d3a19aSMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode GetDepthStart_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cStart, PetscInt *fStart, PetscInt *eStart, PetscInt *vStart)
775d3a19aSMatthew G. Knepley {
875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
975d3a19aSMatthew G. Knepley   if (cStart) *cStart = 0;
1075d3a19aSMatthew G. Knepley   if (vStart) *vStart = depthSize[depth];
1175d3a19aSMatthew G. Knepley   if (fStart) *fStart = depthSize[depth] + depthSize[0];
1275d3a19aSMatthew G. Knepley   if (eStart) *eStart = depthSize[depth] + depthSize[0] + depthSize[depth-1];
1375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
1475d3a19aSMatthew G. Knepley }
1575d3a19aSMatthew G. Knepley 
1675d3a19aSMatthew G. Knepley #undef __FUNCT__
1775d3a19aSMatthew G. Knepley #define __FUNCT__ "GetDepthEnd_Private"
1875d3a19aSMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode GetDepthEnd_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cEnd, PetscInt *fEnd, PetscInt *eEnd, PetscInt *vEnd)
1975d3a19aSMatthew G. Knepley {
2075d3a19aSMatthew G. Knepley   PetscFunctionBegin;
2175d3a19aSMatthew G. Knepley   if (cEnd) *cEnd = depthSize[depth];
2275d3a19aSMatthew G. Knepley   if (vEnd) *vEnd = depthSize[depth] + depthSize[0];
2375d3a19aSMatthew G. Knepley   if (fEnd) *fEnd = depthSize[depth] + depthSize[0] + depthSize[depth-1];
2475d3a19aSMatthew G. Knepley   if (eEnd) *eEnd = depthSize[depth] + depthSize[0] + depthSize[depth-1] + depthSize[1];
2575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
2675d3a19aSMatthew G. Knepley }
2775d3a19aSMatthew G. Knepley 
2875d3a19aSMatthew G. Knepley #undef __FUNCT__
2975d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerGetSizes"
3075d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[])
3175d3a19aSMatthew G. Knepley {
3275d3a19aSMatthew G. Knepley   PetscInt       cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax;
3375d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
3475d3a19aSMatthew G. Knepley 
3575d3a19aSMatthew G. Knepley   PetscFunctionBegin;
3675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
3775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
3875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
3975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
4075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
4175d3a19aSMatthew G. Knepley   switch (refiner) {
4275d3a19aSMatthew G. Knepley   case 1:
4375d3a19aSMatthew G. Knepley     /* Simplicial 2D */
4475d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fEnd - fStart;         /* Add a vertex on every face */
4575d3a19aSMatthew 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 */
4675d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cEnd - cStart);                     /* Every cell split into 4 cells */
4775d3a19aSMatthew G. Knepley     break;
4875d3a19aSMatthew G. Knepley   case 3:
4975d3a19aSMatthew G. Knepley     /* Hybrid 2D */
5075d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
5175d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
5275d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
5375d3a19aSMatthew G. Knepley     fMax         = PetscMin(fEnd, fMax);
5475d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fMax - fStart;                                         /* Add a vertex on every face, but not hybrid faces */
5575d3a19aSMatthew 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 */
5675d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax);                                   /* Interior cells split into 4 cells, Hybrid cells split into 2 cells */
5775d3a19aSMatthew G. Knepley     break;
5875d3a19aSMatthew G. Knepley   case 2:
5975d3a19aSMatthew G. Knepley     /* Hex 2D */
6075d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + cEnd - cStart + fEnd - fStart; /* Add a vertex on every face and cell */
6175d3a19aSMatthew 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 */
6275d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cEnd - cStart);                             /* Every cell split into 4 cells */
6375d3a19aSMatthew G. Knepley     break;
6475d3a19aSMatthew G. Knepley   default:
6575d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
6675d3a19aSMatthew G. Knepley   }
6775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
6875d3a19aSMatthew G. Knepley }
6975d3a19aSMatthew G. Knepley 
7075d3a19aSMatthew G. Knepley #undef __FUNCT__
7175d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetConeSizes"
7275d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
7375d3a19aSMatthew G. Knepley {
7475d3a19aSMatthew G. Knepley   PetscInt       depth, cStart, cStartNew, cEnd, cMax, c, vStart, vStartNew, vEnd, vMax, v, fStart, fStartNew, fEnd, fMax, f, eStart, eStartNew, eEnd, eMax, r;
7575d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
7675d3a19aSMatthew G. Knepley 
7775d3a19aSMatthew G. Knepley   PetscFunctionBegin;
7875d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
7975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
8075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
8175d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
8275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
8375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
8475d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
8575d3a19aSMatthew G. Knepley   switch (refiner) {
8675d3a19aSMatthew G. Knepley   case 1:
8775d3a19aSMatthew G. Knepley     /* Simplicial 2D */
8875d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
8975d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
9075d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
9175d3a19aSMatthew G. Knepley         const PetscInt newp = (c - cStart)*4 + r;
9275d3a19aSMatthew G. Knepley 
9375d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
9475d3a19aSMatthew G. Knepley       }
9575d3a19aSMatthew G. Knepley     }
9675d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
9775d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
9875d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
9975d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
10075d3a19aSMatthew G. Knepley         PetscInt       size;
10175d3a19aSMatthew G. Knepley 
10275d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
10375d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
10475d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
10575d3a19aSMatthew G. Knepley       }
10675d3a19aSMatthew G. Knepley     }
10775d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
10875d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
10975d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
11075d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
11175d3a19aSMatthew G. Knepley 
11275d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
11375d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
11475d3a19aSMatthew G. Knepley       }
11575d3a19aSMatthew G. Knepley     }
11675d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
11775d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
11875d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
11975d3a19aSMatthew G. Knepley       PetscInt       size;
12075d3a19aSMatthew G. Knepley 
12175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
12275d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
12375d3a19aSMatthew G. Knepley     }
12475d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
12575d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
12675d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
12775d3a19aSMatthew G. Knepley       PetscInt       size;
12875d3a19aSMatthew G. Knepley 
12975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
13075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr);
13175d3a19aSMatthew G. Knepley     }
13275d3a19aSMatthew G. Knepley     break;
13375d3a19aSMatthew G. Knepley   case 2:
13475d3a19aSMatthew G. Knepley     /* Hex 2D */
13575d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
13675d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
13775d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
13875d3a19aSMatthew G. Knepley         const PetscInt newp = (c - cStart)*4 + r;
13975d3a19aSMatthew G. Knepley 
14075d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
14175d3a19aSMatthew G. Knepley       }
14275d3a19aSMatthew G. Knepley     }
14375d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
14475d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
14575d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
14675d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
14775d3a19aSMatthew G. Knepley         PetscInt       size;
14875d3a19aSMatthew G. Knepley 
14975d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
15075d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
15175d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
15275d3a19aSMatthew G. Knepley       }
15375d3a19aSMatthew G. Knepley     }
15475d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
15575d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
15675d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
15775d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
15875d3a19aSMatthew G. Knepley 
15975d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
16075d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
16175d3a19aSMatthew G. Knepley       }
16275d3a19aSMatthew G. Knepley     }
16375d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
16475d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
16575d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
16675d3a19aSMatthew G. Knepley       PetscInt       size;
16775d3a19aSMatthew G. Knepley 
16875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
16975d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
17075d3a19aSMatthew G. Knepley     }
17175d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
17275d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
17375d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
17475d3a19aSMatthew G. Knepley       PetscInt       size;
17575d3a19aSMatthew G. Knepley 
17675d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
17775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
17875d3a19aSMatthew G. Knepley     }
17975d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
18075d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
18175d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
18275d3a19aSMatthew G. Knepley 
18375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
18475d3a19aSMatthew G. Knepley     }
18575d3a19aSMatthew G. Knepley     break;
18675d3a19aSMatthew G. Knepley   case 3:
18775d3a19aSMatthew G. Knepley     /* Hybrid 2D */
18875d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
18975d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
19075d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
19175d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
19275d3a19aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
19375d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
19475d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
19575d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
19675d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
19775d3a19aSMatthew G. Knepley 
19875d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
19975d3a19aSMatthew G. Knepley       }
20075d3a19aSMatthew G. Knepley     }
20175d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
20275d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
20375d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
20475d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
20575d3a19aSMatthew G. Knepley 
20675d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
20775d3a19aSMatthew G. Knepley       }
20875d3a19aSMatthew G. Knepley     }
20975d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
21075d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
21175d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
21275d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
21375d3a19aSMatthew G. Knepley         PetscInt       size;
21475d3a19aSMatthew G. Knepley 
21575d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
21675d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
21775d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
21875d3a19aSMatthew G. Knepley       }
21975d3a19aSMatthew G. Knepley     }
22075d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
22175d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
22275d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
22375d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
22475d3a19aSMatthew G. Knepley 
22575d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
22675d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
22775d3a19aSMatthew G. Knepley       }
22875d3a19aSMatthew G. Knepley     }
22975d3a19aSMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
23075d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
23175d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
23275d3a19aSMatthew G. Knepley       PetscInt       size;
23375d3a19aSMatthew G. Knepley 
23475d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
23575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
23675d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
23775d3a19aSMatthew G. Knepley     }
23875d3a19aSMatthew G. Knepley     /* Hybrid cell faces have 2 vertices and 2 cells */
23975d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
24075d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
24175d3a19aSMatthew G. Knepley 
24275d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
24375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
24475d3a19aSMatthew G. Knepley     }
24575d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
24675d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
24775d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
24875d3a19aSMatthew G. Knepley       PetscInt       size;
24975d3a19aSMatthew G. Knepley 
25075d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
25175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
25275d3a19aSMatthew G. Knepley     }
25375d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
25475d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
25575d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
25675d3a19aSMatthew G. Knepley       const PetscInt *support;
25775d3a19aSMatthew G. Knepley       PetscInt       size, newSize = 2, s;
25875d3a19aSMatthew G. Knepley 
25975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
26075d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
26175d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
26275d3a19aSMatthew G. Knepley         if (support[s] >= cMax) newSize += 1;
26375d3a19aSMatthew G. Knepley         else newSize += 2;
26475d3a19aSMatthew G. Knepley       }
26575d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr);
26675d3a19aSMatthew G. Knepley     }
26775d3a19aSMatthew G. Knepley     break;
26875d3a19aSMatthew G. Knepley   default:
26975d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
27075d3a19aSMatthew G. Knepley   }
27175d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
27275d3a19aSMatthew G. Knepley }
27375d3a19aSMatthew G. Knepley 
27475d3a19aSMatthew G. Knepley #undef __FUNCT__
27575d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCones"
27675d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
27775d3a19aSMatthew G. Knepley {
27875d3a19aSMatthew G. Knepley   PetscInt       depth, cStart, cEnd, cMax, cStartNew, cEndNew, c, vStart, vEnd, vMax, vStartNew, vEndNew, v, fStart, fEnd, fMax, fStartNew, fEndNew, f, eStart, eEnd, eMax, eStartNew, eEndNew, r, p;
27975d3a19aSMatthew G. Knepley   PetscInt       maxSupportSize, *supportRef;
28075d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
28175d3a19aSMatthew G. Knepley 
28275d3a19aSMatthew G. Knepley   PetscFunctionBegin;
28375d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
28475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
28575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
28675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
28775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
28875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
28975d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
29075d3a19aSMatthew G. Knepley   ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr);
29175d3a19aSMatthew G. Knepley   switch (refiner) {
29275d3a19aSMatthew G. Knepley   case 1:
29375d3a19aSMatthew G. Knepley     /* Simplicial 2D */
29475d3a19aSMatthew G. Knepley     /*
29575d3a19aSMatthew G. Knepley      2
29675d3a19aSMatthew G. Knepley      |\
29775d3a19aSMatthew G. Knepley      | \
29875d3a19aSMatthew G. Knepley      |  \
29975d3a19aSMatthew G. Knepley      |   \
30075d3a19aSMatthew G. Knepley      | C  \
30175d3a19aSMatthew G. Knepley      |     \
30275d3a19aSMatthew G. Knepley      |      \
30375d3a19aSMatthew G. Knepley      2---1---1
30475d3a19aSMatthew G. Knepley      |\  D  / \
30575d3a19aSMatthew G. Knepley      | 2   0   \
30675d3a19aSMatthew G. Knepley      |A \ /  B  \
30775d3a19aSMatthew G. Knepley      0---0-------1
30875d3a19aSMatthew G. Knepley      */
30975d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
31075d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
31175d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
31275d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
31375d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
31475d3a19aSMatthew G. Knepley 
31575d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
31675d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
31775d3a19aSMatthew G. Knepley       /* A triangle */
31875d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
31975d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
32075d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
32175d3a19aSMatthew G. Knepley       orntNew[1] = -2;
32275d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
32375d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
32475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
32575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
32675d3a19aSMatthew G. Knepley #if 1
32775d3a19aSMatthew 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);
32875d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
32975d3a19aSMatthew 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);
33075d3a19aSMatthew G. Knepley       }
33175d3a19aSMatthew G. Knepley #endif
33275d3a19aSMatthew G. Knepley       /* B triangle */
33375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
33475d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
33575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
33675d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
33775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
33875d3a19aSMatthew G. Knepley       orntNew[2] = -2;
33975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
34075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
34175d3a19aSMatthew G. Knepley #if 1
34275d3a19aSMatthew 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);
34375d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
34475d3a19aSMatthew 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);
34575d3a19aSMatthew G. Knepley       }
34675d3a19aSMatthew G. Knepley #endif
34775d3a19aSMatthew G. Knepley       /* C triangle */
34875d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
34975d3a19aSMatthew G. Knepley       orntNew[0] = -2;
35075d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
35175d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
35275d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
35375d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
35475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
35575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
35675d3a19aSMatthew G. Knepley #if 1
35775d3a19aSMatthew 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);
35875d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
35975d3a19aSMatthew 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);
36075d3a19aSMatthew G. Knepley       }
36175d3a19aSMatthew G. Knepley #endif
36275d3a19aSMatthew G. Knepley       /* D triangle */
36375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
36475d3a19aSMatthew G. Knepley       orntNew[0] = 0;
36575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
36675d3a19aSMatthew G. Knepley       orntNew[1] = 0;
36775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
36875d3a19aSMatthew G. Knepley       orntNew[2] = 0;
36975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
37075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
37175d3a19aSMatthew G. Knepley #if 1
37275d3a19aSMatthew 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);
37375d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
37475d3a19aSMatthew 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);
37575d3a19aSMatthew G. Knepley       }
37675d3a19aSMatthew G. Knepley #endif
37775d3a19aSMatthew G. Knepley     }
37875d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
37975d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
38075d3a19aSMatthew G. Knepley     ierr = PetscMalloc((2 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr);
38175d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
38275d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
38375d3a19aSMatthew G. Knepley 
38475d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
38575d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
38675d3a19aSMatthew G. Knepley         const PetscInt *cone, *support;
38775d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
38875d3a19aSMatthew G. Knepley 
38975d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
39075d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
39175d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
39275d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
39375d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
39475d3a19aSMatthew G. Knepley #if 1
39575d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
39675d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
39775d3a19aSMatthew 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);
39875d3a19aSMatthew G. Knepley         }
39975d3a19aSMatthew G. Knepley #endif
40075d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
40175d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
40275d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
40375d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
40475d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
40575d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
40675d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
40775d3a19aSMatthew G. Knepley           }
40875d3a19aSMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (c+r)%3;
40975d3a19aSMatthew G. Knepley         }
41075d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
41175d3a19aSMatthew G. Knepley #if 1
41275d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
41375d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
41475d3a19aSMatthew 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);
41575d3a19aSMatthew G. Knepley         }
41675d3a19aSMatthew G. Knepley #endif
41775d3a19aSMatthew G. Knepley       }
41875d3a19aSMatthew G. Knepley     }
41975d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
42075d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
42175d3a19aSMatthew G. Knepley       const PetscInt *cone;
42275d3a19aSMatthew G. Knepley 
42375d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
42475d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
42575d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
42675d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
42775d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
42875d3a19aSMatthew G. Knepley 
42975d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
43075d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
43175d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
43275d3a19aSMatthew G. Knepley #if 1
43375d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
43475d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
43575d3a19aSMatthew 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);
43675d3a19aSMatthew G. Knepley         }
43775d3a19aSMatthew G. Knepley #endif
43875d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
43975d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
44075d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
44175d3a19aSMatthew G. Knepley #if 1
44275d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
44375d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
44475d3a19aSMatthew 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);
44575d3a19aSMatthew G. Knepley         }
44675d3a19aSMatthew G. Knepley #endif
44775d3a19aSMatthew G. Knepley       }
44875d3a19aSMatthew G. Knepley     }
44975d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
45075d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
45175d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
45275d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
45375d3a19aSMatthew G. Knepley       PetscInt        size, s;
45475d3a19aSMatthew G. Knepley 
45575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
45675d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
45775d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
45875d3a19aSMatthew G. Knepley         PetscInt r = 0;
45975d3a19aSMatthew G. Knepley 
46075d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
46175d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
46275d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
46375d3a19aSMatthew G. Knepley       }
46475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
46575d3a19aSMatthew G. Knepley #if 1
46675d3a19aSMatthew 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);
46775d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
46875d3a19aSMatthew 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);
46975d3a19aSMatthew G. Knepley       }
47075d3a19aSMatthew G. Knepley #endif
47175d3a19aSMatthew G. Knepley     }
47275d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
47375d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
47475d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
47575d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
47675d3a19aSMatthew G. Knepley       PetscInt        size, s;
47775d3a19aSMatthew G. Knepley 
47875d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
47975d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
48075d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
48175d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
48275d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
48375d3a19aSMatthew G. Knepley         PetscInt r = 0;
48475d3a19aSMatthew G. Knepley 
48575d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
48675d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
48775d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
48875d3a19aSMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
48975d3a19aSMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
49075d3a19aSMatthew G. Knepley       }
49175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
49275d3a19aSMatthew G. Knepley #if 1
49375d3a19aSMatthew 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);
49475d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
49575d3a19aSMatthew 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);
49675d3a19aSMatthew G. Knepley       }
49775d3a19aSMatthew G. Knepley #endif
49875d3a19aSMatthew G. Knepley     }
49975d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
50075d3a19aSMatthew G. Knepley     break;
50175d3a19aSMatthew G. Knepley   case 2:
50275d3a19aSMatthew G. Knepley     /* Hex 2D */
50375d3a19aSMatthew G. Knepley     /*
50475d3a19aSMatthew G. Knepley      3---------2---------2
50575d3a19aSMatthew G. Knepley      |         |         |
50675d3a19aSMatthew G. Knepley      |    D    2    C    |
50775d3a19aSMatthew G. Knepley      |         |         |
50875d3a19aSMatthew G. Knepley      3----3----0----1----1
50975d3a19aSMatthew G. Knepley      |         |         |
51075d3a19aSMatthew G. Knepley      |    A    0    B    |
51175d3a19aSMatthew G. Knepley      |         |         |
51275d3a19aSMatthew G. Knepley      0---------0---------1
51375d3a19aSMatthew G. Knepley      */
51475d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
51575d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
51675d3a19aSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*4;
51775d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
51875d3a19aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
51975d3a19aSMatthew G. Knepley 
52075d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
52175d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
52275d3a19aSMatthew G. Knepley       /* A quad */
52375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
52475d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
52575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
52675d3a19aSMatthew G. Knepley       orntNew[1] = 0;
52775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
52875d3a19aSMatthew G. Knepley       orntNew[2] = -2;
52975d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
53075d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
53175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
53275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
53375d3a19aSMatthew G. Knepley #if 1
53475d3a19aSMatthew 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);
53575d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
53675d3a19aSMatthew 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);
53775d3a19aSMatthew G. Knepley       }
53875d3a19aSMatthew G. Knepley #endif
53975d3a19aSMatthew G. Knepley       /* B quad */
54075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
54175d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
54275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
54375d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
54475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
54575d3a19aSMatthew G. Knepley       orntNew[2] = 0;
54675d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
54775d3a19aSMatthew G. Knepley       orntNew[3] = -2;
54875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
54975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
55075d3a19aSMatthew G. Knepley #if 1
55175d3a19aSMatthew 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);
55275d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
55375d3a19aSMatthew 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);
55475d3a19aSMatthew G. Knepley       }
55575d3a19aSMatthew G. Knepley #endif
55675d3a19aSMatthew G. Knepley       /* C quad */
55775d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
55875d3a19aSMatthew G. Knepley       orntNew[0] = -2;
55975d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
56075d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
56175d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
56275d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
56375d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
56475d3a19aSMatthew G. Knepley       orntNew[3] = 0;
56575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
56675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
56775d3a19aSMatthew G. Knepley #if 1
56875d3a19aSMatthew 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);
56975d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
57075d3a19aSMatthew 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);
57175d3a19aSMatthew G. Knepley       }
57275d3a19aSMatthew G. Knepley #endif
57375d3a19aSMatthew G. Knepley       /* D quad */
57475d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
57575d3a19aSMatthew G. Knepley       orntNew[0] = 0;
57675d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
57775d3a19aSMatthew G. Knepley       orntNew[1] = -2;
57875d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
57975d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
58075d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
58175d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
58275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
58375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
58475d3a19aSMatthew G. Knepley #if 1
58575d3a19aSMatthew 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);
58675d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
58775d3a19aSMatthew 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);
58875d3a19aSMatthew G. Knepley       }
58975d3a19aSMatthew G. Knepley #endif
59075d3a19aSMatthew G. Knepley     }
59175d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
59275d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
59375d3a19aSMatthew G. Knepley     ierr = PetscMalloc((2 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr);
59475d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
59575d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
59675d3a19aSMatthew G. Knepley 
59775d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
59875d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
59975d3a19aSMatthew G. Knepley         const PetscInt *cone, *support;
60075d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
60175d3a19aSMatthew G. Knepley 
60275d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
60375d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
60475d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
60575d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
60675d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
60775d3a19aSMatthew G. Knepley #if 1
60875d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
60975d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
61075d3a19aSMatthew 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);
61175d3a19aSMatthew G. Knepley         }
61275d3a19aSMatthew G. Knepley #endif
61375d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
61475d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
61575d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
61675d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
61775d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
61875d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
61975d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
62075d3a19aSMatthew G. Knepley           }
62175d3a19aSMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (c+r)%4;
62275d3a19aSMatthew G. Knepley         }
62375d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
62475d3a19aSMatthew G. Knepley #if 1
62575d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
62675d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
62775d3a19aSMatthew 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);
62875d3a19aSMatthew G. Knepley         }
62975d3a19aSMatthew G. Knepley #endif
63075d3a19aSMatthew G. Knepley       }
63175d3a19aSMatthew G. Knepley     }
63275d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
63375d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
63475d3a19aSMatthew G. Knepley       const PetscInt *cone;
63575d3a19aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
63675d3a19aSMatthew G. Knepley 
63775d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
63875d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
63975d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
64075d3a19aSMatthew G. Knepley 
64175d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
64275d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd    - fStart) + (c - cStart);
64375d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
64475d3a19aSMatthew G. Knepley #if 1
64575d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
64675d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
64775d3a19aSMatthew 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);
64875d3a19aSMatthew G. Knepley         }
64975d3a19aSMatthew G. Knepley #endif
65075d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
65175d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
65275d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
65375d3a19aSMatthew G. Knepley #if 1
65475d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
65575d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
65675d3a19aSMatthew 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);
65775d3a19aSMatthew G. Knepley         }
65875d3a19aSMatthew G. Knepley #endif
65975d3a19aSMatthew G. Knepley       }
66075d3a19aSMatthew G. Knepley     }
66175d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
66275d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
66375d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
66475d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
66575d3a19aSMatthew G. Knepley       PetscInt        size, s;
66675d3a19aSMatthew G. Knepley 
66775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
66875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
66975d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
67075d3a19aSMatthew G. Knepley         PetscInt r = 0;
67175d3a19aSMatthew G. Knepley 
67275d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
67375d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
67475d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
67575d3a19aSMatthew G. Knepley       }
67675d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
67775d3a19aSMatthew G. Knepley #if 1
67875d3a19aSMatthew 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);
67975d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
68075d3a19aSMatthew 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);
68175d3a19aSMatthew G. Knepley       }
68275d3a19aSMatthew G. Knepley #endif
68375d3a19aSMatthew G. Knepley     }
68475d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
68575d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
68675d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
68775d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
68875d3a19aSMatthew G. Knepley       PetscInt        size, s;
68975d3a19aSMatthew G. Knepley 
69075d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
69175d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
69275d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
69375d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
69475d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
69575d3a19aSMatthew G. Knepley         PetscInt r = 0;
69675d3a19aSMatthew G. Knepley 
69775d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
69875d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
69975d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
70075d3a19aSMatthew G. Knepley         else if (cone[3] == f) r = 3;
70175d3a19aSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r;
70275d3a19aSMatthew G. Knepley       }
70375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
70475d3a19aSMatthew G. Knepley #if 1
70575d3a19aSMatthew 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);
70675d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
70775d3a19aSMatthew 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);
70875d3a19aSMatthew G. Knepley       }
70975d3a19aSMatthew G. Knepley #endif
71075d3a19aSMatthew G. Knepley     }
71175d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
71275d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
71375d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
71475d3a19aSMatthew G. Knepley       PetscInt       supportNew[4];
71575d3a19aSMatthew G. Knepley 
71675d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
71775d3a19aSMatthew G. Knepley         supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
71875d3a19aSMatthew G. Knepley       }
71975d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
72075d3a19aSMatthew G. Knepley     }
72175d3a19aSMatthew G. Knepley     break;
72275d3a19aSMatthew G. Knepley   case 3:
72375d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
72475d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
72575d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
72675d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
72775d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
72875d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
72975d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
73075d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
73175d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
73275d3a19aSMatthew G. Knepley 
73375d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
73475d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
73575d3a19aSMatthew G. Knepley       /* A triangle */
73675d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
73775d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
73875d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
73975d3a19aSMatthew G. Knepley       orntNew[1] = -2;
74075d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
74175d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
74275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
74375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
74475d3a19aSMatthew G. Knepley #if 1
74575d3a19aSMatthew 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);
74675d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
74775d3a19aSMatthew 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);
74875d3a19aSMatthew G. Knepley       }
74975d3a19aSMatthew G. Knepley #endif
75075d3a19aSMatthew G. Knepley       /* B triangle */
75175d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
75275d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
75375d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
75475d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
75575d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
75675d3a19aSMatthew G. Knepley       orntNew[2] = -2;
75775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
75875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
75975d3a19aSMatthew G. Knepley #if 1
76075d3a19aSMatthew 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);
76175d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
76275d3a19aSMatthew 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);
76375d3a19aSMatthew G. Knepley       }
76475d3a19aSMatthew G. Knepley #endif
76575d3a19aSMatthew G. Knepley       /* C triangle */
76675d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
76775d3a19aSMatthew G. Knepley       orntNew[0] = -2;
76875d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
76975d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
77075d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
77175d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
77275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
77375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
77475d3a19aSMatthew G. Knepley #if 1
77575d3a19aSMatthew 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);
77675d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
77775d3a19aSMatthew 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);
77875d3a19aSMatthew G. Knepley       }
77975d3a19aSMatthew G. Knepley #endif
78075d3a19aSMatthew G. Knepley       /* D triangle */
78175d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
78275d3a19aSMatthew G. Knepley       orntNew[0] = 0;
78375d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
78475d3a19aSMatthew G. Knepley       orntNew[1] = 0;
78575d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
78675d3a19aSMatthew G. Knepley       orntNew[2] = 0;
78775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
78875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
78975d3a19aSMatthew G. Knepley #if 1
79075d3a19aSMatthew 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);
79175d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
79275d3a19aSMatthew 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);
79375d3a19aSMatthew G. Knepley       }
79475d3a19aSMatthew G. Knepley #endif
79575d3a19aSMatthew G. Knepley     }
79675d3a19aSMatthew G. Knepley     /*
79775d3a19aSMatthew G. Knepley      2----3----3
79875d3a19aSMatthew G. Knepley      |         |
79975d3a19aSMatthew G. Knepley      |    B    |
80075d3a19aSMatthew G. Knepley      |         |
80175d3a19aSMatthew G. Knepley      0----4--- 1
80275d3a19aSMatthew G. Knepley      |         |
80375d3a19aSMatthew G. Knepley      |    A    |
80475d3a19aSMatthew G. Knepley      |         |
80575d3a19aSMatthew G. Knepley      0----2----1
80675d3a19aSMatthew G. Knepley      */
80775d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
80875d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
80975d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
81075d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
81175d3a19aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
81275d3a19aSMatthew G. Knepley 
81375d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
81475d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
81575d3a19aSMatthew G. Knepley       /* A quad */
81675d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
81775d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
81875d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
81975d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
82075d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[2] - fMax);
82175d3a19aSMatthew G. Knepley       orntNew[2] = 0;
82275d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
82375d3a19aSMatthew G. Knepley       orntNew[3] = 0;
82475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
82575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
82675d3a19aSMatthew G. Knepley #if 1
82775d3a19aSMatthew 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);
82875d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
82975d3a19aSMatthew 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);
83075d3a19aSMatthew G. Knepley       }
83175d3a19aSMatthew G. Knepley #endif
83275d3a19aSMatthew G. Knepley       /* B quad */
83375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
83475d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
83575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
83675d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
83775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
83875d3a19aSMatthew G. Knepley       orntNew[2] = 0;
83975d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[3] - fMax);
84075d3a19aSMatthew G. Knepley       orntNew[3] = 0;
84175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
84275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
84375d3a19aSMatthew G. Knepley #if 1
84475d3a19aSMatthew 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);
84575d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
84675d3a19aSMatthew 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);
84775d3a19aSMatthew G. Knepley       }
84875d3a19aSMatthew G. Knepley #endif
84975d3a19aSMatthew G. Knepley     }
85075d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
85175d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
85275d3a19aSMatthew G. Knepley     ierr = PetscMalloc((2 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr);
85375d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
85475d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
85575d3a19aSMatthew G. Knepley 
85675d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
85775d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
85875d3a19aSMatthew G. Knepley         const PetscInt *cone, *support;
85975d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
86075d3a19aSMatthew G. Knepley 
86175d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
86275d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
86375d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
86475d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
86575d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
86675d3a19aSMatthew G. Knepley #if 1
86775d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
86875d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
86975d3a19aSMatthew 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);
87075d3a19aSMatthew G. Knepley         }
87175d3a19aSMatthew G. Knepley #endif
87275d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
87375d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
87475d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
87575d3a19aSMatthew G. Knepley           if (support[s] >= cMax) {
87675d3a19aSMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
87775d3a19aSMatthew G. Knepley           } else {
87875d3a19aSMatthew G. Knepley             ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
87975d3a19aSMatthew G. Knepley             ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
88075d3a19aSMatthew G. Knepley             for (c = 0; c < coneSize; ++c) {
88175d3a19aSMatthew G. Knepley               if (cone[c] == f) break;
88275d3a19aSMatthew G. Knepley             }
88375d3a19aSMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (c+r)%3;
88475d3a19aSMatthew G. Knepley           }
88575d3a19aSMatthew G. Knepley         }
88675d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
88775d3a19aSMatthew G. Knepley #if 1
88875d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
88975d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
89075d3a19aSMatthew 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);
89175d3a19aSMatthew G. Knepley         }
89275d3a19aSMatthew G. Knepley #endif
89375d3a19aSMatthew G. Knepley       }
89475d3a19aSMatthew G. Knepley     }
89575d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
89675d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
89775d3a19aSMatthew G. Knepley       const PetscInt *cone;
89875d3a19aSMatthew G. Knepley 
89975d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
90075d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
90175d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
90275d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
90375d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
90475d3a19aSMatthew G. Knepley 
90575d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
90675d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
90775d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
90875d3a19aSMatthew G. Knepley #if 1
90975d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
91075d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
91175d3a19aSMatthew 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);
91275d3a19aSMatthew G. Knepley         }
91375d3a19aSMatthew G. Knepley #endif
91475d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
91575d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
91675d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
91775d3a19aSMatthew G. Knepley #if 1
91875d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
91975d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
92075d3a19aSMatthew 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);
92175d3a19aSMatthew G. Knepley         }
92275d3a19aSMatthew G. Knepley #endif
92375d3a19aSMatthew G. Knepley       }
92475d3a19aSMatthew G. Knepley     }
92575d3a19aSMatthew G. Knepley     /* Interior hybrid faces have 2 vertices and the same cells */
92675d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
92775d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
92875d3a19aSMatthew G. Knepley       const PetscInt *cone;
92975d3a19aSMatthew G. Knepley       const PetscInt *support;
93075d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
93175d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
93275d3a19aSMatthew G. Knepley       PetscInt        size, s, r;
93375d3a19aSMatthew G. Knepley 
93475d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
93575d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
93675d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
93775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
93875d3a19aSMatthew G. Knepley #if 1
93975d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
94075d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
94175d3a19aSMatthew 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);
94275d3a19aSMatthew G. Knepley       }
94375d3a19aSMatthew G. Knepley #endif
94475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
94575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
94675d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
94775d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
94875d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r) {
94975d3a19aSMatthew G. Knepley           if (cone[r+2] == f) break;
95075d3a19aSMatthew G. Knepley         }
95175d3a19aSMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
95275d3a19aSMatthew G. Knepley       }
95375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
95475d3a19aSMatthew G. Knepley #if 1
95575d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
95675d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
95775d3a19aSMatthew 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);
95875d3a19aSMatthew G. Knepley       }
95975d3a19aSMatthew G. Knepley #endif
96075d3a19aSMatthew G. Knepley     }
96175d3a19aSMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
96275d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
96375d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
96475d3a19aSMatthew G. Knepley       const PetscInt *cone;
96575d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
96675d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
96775d3a19aSMatthew G. Knepley 
96875d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
96975d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
97075d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
97175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
97275d3a19aSMatthew G. Knepley #if 1
97375d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
97475d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
97575d3a19aSMatthew 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);
97675d3a19aSMatthew G. Knepley       }
97775d3a19aSMatthew G. Knepley #endif
97875d3a19aSMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
97975d3a19aSMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
98075d3a19aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
98175d3a19aSMatthew G. Knepley #if 1
98275d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
98375d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
98475d3a19aSMatthew 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);
98575d3a19aSMatthew G. Knepley       }
98675d3a19aSMatthew G. Knepley #endif
98775d3a19aSMatthew G. Knepley     }
98875d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
98975d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
99075d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
99175d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
99275d3a19aSMatthew G. Knepley       PetscInt        size, s;
99375d3a19aSMatthew G. Knepley 
99475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
99575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
99675d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
99775d3a19aSMatthew G. Knepley         if (support[s] >= fMax) {
99875d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax);
99975d3a19aSMatthew G. Knepley         } else {
100075d3a19aSMatthew G. Knepley           PetscInt r = 0;
100175d3a19aSMatthew G. Knepley 
100275d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
100375d3a19aSMatthew G. Knepley           if (cone[1] == v) r = 1;
100475d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
100575d3a19aSMatthew G. Knepley         }
100675d3a19aSMatthew G. Knepley       }
100775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
100875d3a19aSMatthew G. Knepley #if 1
100975d3a19aSMatthew 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);
101075d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
101175d3a19aSMatthew 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);
101275d3a19aSMatthew G. Knepley       }
101375d3a19aSMatthew G. Knepley #endif
101475d3a19aSMatthew G. Knepley     }
101575d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
101675d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
101775d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
101875d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
101975d3a19aSMatthew G. Knepley       PetscInt        size, newSize = 2, s;
102075d3a19aSMatthew G. Knepley 
102175d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
102275d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
102375d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
102475d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
102575d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
102675d3a19aSMatthew G. Knepley         PetscInt r = 0;
102775d3a19aSMatthew G. Knepley 
102875d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
102975d3a19aSMatthew G. Knepley         if (support[s] >= cMax) {
103075d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax);
103175d3a19aSMatthew G. Knepley 
103275d3a19aSMatthew G. Knepley           newSize += 1;
103375d3a19aSMatthew G. Knepley         } else {
103475d3a19aSMatthew G. Knepley           if      (cone[1] == f) r = 1;
103575d3a19aSMatthew G. Knepley           else if (cone[2] == f) r = 2;
103675d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
103775d3a19aSMatthew G. Knepley           supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r;
103875d3a19aSMatthew G. Knepley 
103975d3a19aSMatthew G. Knepley           newSize += 2;
104075d3a19aSMatthew G. Knepley         }
104175d3a19aSMatthew G. Knepley       }
104275d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
104375d3a19aSMatthew G. Knepley #if 1
104475d3a19aSMatthew 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);
104575d3a19aSMatthew G. Knepley       for (p = 0; p < newSize; ++p) {
104675d3a19aSMatthew 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);
104775d3a19aSMatthew G. Knepley       }
104875d3a19aSMatthew G. Knepley #endif
104975d3a19aSMatthew G. Knepley     }
105075d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
105175d3a19aSMatthew G. Knepley     break;
105275d3a19aSMatthew G. Knepley   default:
105375d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
105475d3a19aSMatthew G. Knepley   }
105575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
105675d3a19aSMatthew G. Knepley }
105775d3a19aSMatthew G. Knepley 
105875d3a19aSMatthew G. Knepley #undef __FUNCT__
105975d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCoordinates"
106075d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
106175d3a19aSMatthew G. Knepley {
106275d3a19aSMatthew G. Knepley   PetscSection   coordSection, coordSectionNew;
106375d3a19aSMatthew G. Knepley   Vec            coordinates, coordinatesNew;
106475d3a19aSMatthew G. Knepley   PetscScalar   *coords, *coordsNew;
106575d3a19aSMatthew G. Knepley   PetscInt       dim, depth, coordSizeNew, cStart, cEnd, c, vStart, vStartNew, vEnd, v, fStart, fEnd, fMax, f;
106675d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
106775d3a19aSMatthew G. Knepley 
106875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
106975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
107075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
107175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
107275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
107375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
107475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, NULL, &fMax, NULL, NULL);CHKERRQ(ierr);
107575d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);
107675d3a19aSMatthew G. Knepley   ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
107775d3a19aSMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr);
107875d3a19aSMatthew G. Knepley   ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr);
107975d3a19aSMatthew G. Knepley   ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dim);CHKERRQ(ierr);
108075d3a19aSMatthew G. Knepley   ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+depthSize[0]);CHKERRQ(ierr);
108175d3a19aSMatthew G. Knepley   if (fMax < 0) fMax = fEnd;
108275d3a19aSMatthew G. Knepley   switch (refiner) {
108375d3a19aSMatthew G. Knepley   case 1:
108475d3a19aSMatthew G. Knepley   case 2:
108575d3a19aSMatthew G. Knepley   case 3:
108675d3a19aSMatthew G. Knepley     /* Simplicial and Hex 2D */
108775d3a19aSMatthew G. Knepley     /* All vertices have the dim coordinates */
108875d3a19aSMatthew G. Knepley     for (v = vStartNew; v < vStartNew+depthSize[0]; ++v) {
108975d3a19aSMatthew G. Knepley       ierr = PetscSectionSetDof(coordSectionNew, v, dim);CHKERRQ(ierr);
109075d3a19aSMatthew G. Knepley       ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dim);CHKERRQ(ierr);
109175d3a19aSMatthew G. Knepley     }
109275d3a19aSMatthew G. Knepley     ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr);
109375d3a19aSMatthew G. Knepley     ierr = DMPlexSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr);
109475d3a19aSMatthew G. Knepley     ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
109575d3a19aSMatthew G. Knepley     ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr);
109675d3a19aSMatthew G. Knepley     ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr);
109775d3a19aSMatthew G. Knepley     ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr);
109875d3a19aSMatthew G. Knepley     ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr);
109975d3a19aSMatthew G. Knepley     ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr);
110075d3a19aSMatthew G. Knepley     ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr);
110175d3a19aSMatthew G. Knepley     ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
110275d3a19aSMatthew G. Knepley     /* Old vertices have the same coordinates */
110375d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
110475d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (v - vStart);
110575d3a19aSMatthew G. Knepley       PetscInt       off, offnew, d;
110675d3a19aSMatthew G. Knepley 
110775d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr);
110875d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
110975d3a19aSMatthew G. Knepley       for (d = 0; d < dim; ++d) {
111075d3a19aSMatthew G. Knepley         coordsNew[offnew+d] = coords[off+d];
111175d3a19aSMatthew G. Knepley       }
111275d3a19aSMatthew G. Knepley     }
111375d3a19aSMatthew G. Knepley     /* Face vertices have the average of endpoint coordinates */
111475d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
111575d3a19aSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (f - fStart);
111675d3a19aSMatthew G. Knepley       const PetscInt *cone;
111775d3a19aSMatthew G. Knepley       PetscInt        coneSize, offA, offB, offnew, d;
111875d3a19aSMatthew G. Knepley 
111975d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeSize(dm, f, &coneSize);CHKERRQ(ierr);
112075d3a19aSMatthew G. Knepley       if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Face %d cone should have two vertices, not %d", f, coneSize);
112175d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
112275d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr);
112375d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr);
112475d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
112575d3a19aSMatthew G. Knepley       for (d = 0; d < dim; ++d) {
112675d3a19aSMatthew G. Knepley         coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]);
112775d3a19aSMatthew G. Knepley       }
112875d3a19aSMatthew G. Knepley     }
112975d3a19aSMatthew G. Knepley     /* Just Hex 2D */
113075d3a19aSMatthew G. Knepley     if (refiner == 2) {
113175d3a19aSMatthew G. Knepley       /* Cell vertices have the average of corner coordinates */
113275d3a19aSMatthew G. Knepley       for (c = cStart; c < cEnd; ++c) {
113375d3a19aSMatthew G. Knepley         const PetscInt newv = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
113475d3a19aSMatthew G. Knepley         PetscInt      *cone = NULL;
113575d3a19aSMatthew G. Knepley         PetscInt       closureSize, coneSize = 0, offA, offB, offC, offD, offnew, p, d;
113675d3a19aSMatthew G. Knepley 
113775d3a19aSMatthew G. Knepley         ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
113875d3a19aSMatthew G. Knepley         for (p = 0; p < closureSize*2; p += 2) {
113975d3a19aSMatthew G. Knepley           const PetscInt point = cone[p];
114075d3a19aSMatthew G. Knepley           if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
114175d3a19aSMatthew G. Knepley         }
114275d3a19aSMatthew G. Knepley         if (coneSize != 4) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Quad %d cone should have four vertices, not %d", c, coneSize);
114375d3a19aSMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr);
114475d3a19aSMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr);
114575d3a19aSMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[2], &offC);CHKERRQ(ierr);
114675d3a19aSMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[3], &offD);CHKERRQ(ierr);
114775d3a19aSMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
114875d3a19aSMatthew G. Knepley         for (d = 0; d < dim; ++d) {
114975d3a19aSMatthew G. Knepley           coordsNew[offnew+d] = 0.25*(coords[offA+d] + coords[offB+d] + coords[offC+d] + coords[offD+d]);
115075d3a19aSMatthew G. Knepley         }
115175d3a19aSMatthew G. Knepley         ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
115275d3a19aSMatthew G. Knepley       }
115375d3a19aSMatthew G. Knepley     }
115475d3a19aSMatthew G. Knepley     ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr);
115575d3a19aSMatthew G. Knepley     ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
115675d3a19aSMatthew G. Knepley     ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr);
115775d3a19aSMatthew G. Knepley     ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr);
115875d3a19aSMatthew G. Knepley     ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr);
115975d3a19aSMatthew G. Knepley     break;
116075d3a19aSMatthew G. Knepley   default:
116175d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
116275d3a19aSMatthew G. Knepley   }
116375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
116475d3a19aSMatthew G. Knepley }
116575d3a19aSMatthew G. Knepley 
116675d3a19aSMatthew G. Knepley #undef __FUNCT__
116775d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexCreateProcessSF"
116875d3a19aSMatthew G. Knepley PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
116975d3a19aSMatthew G. Knepley {
117075d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, l;
117175d3a19aSMatthew G. Knepley   const PetscInt    *localPoints;
117275d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
117375d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
117475d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
117575d3a19aSMatthew G. Knepley   PetscInt          *ranks, *ranksNew;
117675d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
117775d3a19aSMatthew G. Knepley 
117875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
117975d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
118075d3a19aSMatthew G. Knepley   ierr = PetscMalloc(numLeaves * sizeof(PetscInt), &ranks);CHKERRQ(ierr);
118175d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
118275d3a19aSMatthew G. Knepley     ranks[l] = remotePoints[l].rank;
118375d3a19aSMatthew G. Knepley   }
118475d3a19aSMatthew G. Knepley   ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr);
118575d3a19aSMatthew G. Knepley   ierr = PetscMalloc(numLeaves * sizeof(PetscInt),    &ranksNew);CHKERRQ(ierr);
118675d3a19aSMatthew G. Knepley   ierr = PetscMalloc(numLeaves * sizeof(PetscInt),    &localPointsNew);CHKERRQ(ierr);
118775d3a19aSMatthew G. Knepley   ierr = PetscMalloc(numLeaves * sizeof(PetscSFNode), &remotePointsNew);CHKERRQ(ierr);
118875d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
118975d3a19aSMatthew G. Knepley     ranksNew[l]              = ranks[l];
119075d3a19aSMatthew G. Knepley     localPointsNew[l]        = l;
119175d3a19aSMatthew G. Knepley     remotePointsNew[l].index = 0;
119275d3a19aSMatthew G. Knepley     remotePointsNew[l].rank  = ranksNew[l];
119375d3a19aSMatthew G. Knepley   }
119475d3a19aSMatthew G. Knepley   ierr = PetscFree(ranks);CHKERRQ(ierr);
119575d3a19aSMatthew G. Knepley   ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);
119675d3a19aSMatthew G. Knepley   ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr);
119775d3a19aSMatthew G. Knepley   ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr);
119875d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
119975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
120075d3a19aSMatthew G. Knepley }
120175d3a19aSMatthew G. Knepley 
120275d3a19aSMatthew G. Knepley #undef __FUNCT__
120375d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateSF"
120475d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
120575d3a19aSMatthew G. Knepley {
120675d3a19aSMatthew G. Knepley   PetscSF            sf, sfNew, sfProcess;
120775d3a19aSMatthew G. Knepley   IS                 processRanks;
120875d3a19aSMatthew G. Knepley   MPI_Datatype       depthType;
120975d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, numLeavesNew = 0, l, m;
121075d3a19aSMatthew G. Knepley   const PetscInt    *localPoints, *neighbors;
121175d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
121275d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
121375d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
121475d3a19aSMatthew G. Knepley   PetscInt          *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew;
121575d3a19aSMatthew G. Knepley   PetscInt           depth, numNeighbors, pStartNew, pEndNew, cStart, cStartNew, cEnd, cMax, vStart, vStartNew, vEnd, vMax, fStart, fStartNew, fEnd, fMax, eStart, eStartNew, eEnd, eMax, r, n;
121675d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
121775d3a19aSMatthew G. Knepley 
121875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
121975d3a19aSMatthew G. Knepley   ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr);
122075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
122175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
122275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
122375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
122475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
122575d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
122675d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
122775d3a19aSMatthew G. Knepley   switch (refiner) {
122875d3a19aSMatthew G. Knepley   case 3:
122975d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
123075d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
123175d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
123275d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
123375d3a19aSMatthew G. Knepley   }
123475d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
123575d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr);
123675d3a19aSMatthew G. Knepley   /* Caculate size of new SF */
123775d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
123875d3a19aSMatthew G. Knepley   if (numRoots < 0) PetscFunctionReturn(0);
123975d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
124075d3a19aSMatthew G. Knepley     const PetscInt p = localPoints[l];
124175d3a19aSMatthew G. Knepley 
124275d3a19aSMatthew G. Knepley     switch (refiner) {
124375d3a19aSMatthew G. Knepley     case 1:
124475d3a19aSMatthew G. Knepley       /* Simplicial 2D */
124575d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
124675d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
124775d3a19aSMatthew G. Knepley         ++numLeavesNew;
124875d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
124975d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
125075d3a19aSMatthew G. Knepley         numLeavesNew += 1 + 2;
125175d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
125275d3a19aSMatthew G. Knepley         /* Old cells add new cells and interior faces */
125375d3a19aSMatthew G. Knepley         numLeavesNew += 4 + 3;
125475d3a19aSMatthew G. Knepley       }
125575d3a19aSMatthew G. Knepley       break;
125675d3a19aSMatthew G. Knepley     case 2:
125775d3a19aSMatthew G. Knepley       /* Hex 2D */
125875d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
125975d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
126075d3a19aSMatthew G. Knepley         ++numLeavesNew;
126175d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
126275d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
126375d3a19aSMatthew G. Knepley         numLeavesNew += 1 + 2;
126475d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
126575d3a19aSMatthew G. Knepley         /* Old cells add new cells and interior faces */
126675d3a19aSMatthew G. Knepley         numLeavesNew += 4 + 4;
126775d3a19aSMatthew G. Knepley       }
126875d3a19aSMatthew G. Knepley       break;
126975d3a19aSMatthew G. Knepley     default:
127075d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
127175d3a19aSMatthew G. Knepley     }
127275d3a19aSMatthew G. Knepley   }
127375d3a19aSMatthew G. Knepley   /* Communicate depthSizes for each remote rank */
127475d3a19aSMatthew G. Knepley   ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr);
127575d3a19aSMatthew G. Knepley   ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr);
127675d3a19aSMatthew G. Knepley   ierr = PetscMalloc5((depth+1)*numNeighbors,PetscInt,&rdepthSize,numNeighbors,PetscInt,&rvStartNew,numNeighbors,PetscInt,&reStartNew,numNeighbors,PetscInt,&rfStartNew,numNeighbors,PetscInt,&rcStartNew);CHKERRQ(ierr);
127775d3a19aSMatthew G. Knepley   ierr = PetscMalloc7(depth+1,PetscInt,&depthSizeOld,(depth+1)*numNeighbors,PetscInt,&rdepthSizeOld,(depth+1)*numNeighbors,PetscInt,&rdepthMaxOld,numNeighbors,PetscInt,&rvStart,numNeighbors,PetscInt,&reStart,numNeighbors,PetscInt,&rfStart,numNeighbors,PetscInt,&rcStart);CHKERRQ(ierr);
127875d3a19aSMatthew G. Knepley   ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr);
127975d3a19aSMatthew G. Knepley   ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr);
128075d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
128175d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
128275d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
128375d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr);
128475d3a19aSMatthew G. Knepley   }
128575d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cMax;
128675d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vMax;
128775d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fMax;
128875d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eMax;
128975d3a19aSMatthew G. Knepley 
129075d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
129175d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
129275d3a19aSMatthew G. Knepley 
129375d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cEnd - cStart;
129475d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vEnd - vStart;
129575d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fEnd - fStart;
129675d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eEnd - eStart;
129775d3a19aSMatthew G. Knepley 
129875d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
129975d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
130075d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
130175d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr);
130275d3a19aSMatthew G. Knepley   }
130375d3a19aSMatthew G. Knepley   ierr = MPI_Type_free(&depthType);CHKERRQ(ierr);
130475d3a19aSMatthew G. Knepley   ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr);
130575d3a19aSMatthew G. Knepley   /* Calculate new point SF */
130675d3a19aSMatthew G. Knepley   ierr = PetscMalloc(numLeavesNew * sizeof(PetscInt),    &localPointsNew);CHKERRQ(ierr);
130775d3a19aSMatthew G. Knepley   ierr = PetscMalloc(numLeavesNew * sizeof(PetscSFNode), &remotePointsNew);CHKERRQ(ierr);
130875d3a19aSMatthew G. Knepley   ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr);
130975d3a19aSMatthew G. Knepley   for (l = 0, m = 0; l < numLeaves; ++l) {
131075d3a19aSMatthew G. Knepley     PetscInt    p     = localPoints[l];
131175d3a19aSMatthew G. Knepley     PetscInt    rp    = remotePoints[l].index, n;
131275d3a19aSMatthew G. Knepley     PetscMPIInt rrank = remotePoints[l].rank;
131375d3a19aSMatthew G. Knepley 
131475d3a19aSMatthew G. Knepley     ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr);
131575d3a19aSMatthew G. Knepley     if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank);
131675d3a19aSMatthew G. Knepley     switch (refiner) {
131775d3a19aSMatthew G. Knepley     case 1:
131875d3a19aSMatthew G. Knepley       /* Simplicial 2D */
131975d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
132075d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
132175d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
132275d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
132375d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
132475d3a19aSMatthew G. Knepley         ++m;
132575d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
132675d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
132775d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
132875d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
132975d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
133075d3a19aSMatthew G. Knepley         ++m;
133175d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
133275d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
133375d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
133475d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
133575d3a19aSMatthew G. Knepley         }
133675d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
133775d3a19aSMatthew G. Knepley         /* Old cells add new cells and interior faces */
133875d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
133975d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
134075d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
134175d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
134275d3a19aSMatthew G. Knepley         }
134375d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
134475d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*2                    + (p  - cStart)*3     + r;
134575d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r;
134675d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
134775d3a19aSMatthew G. Knepley         }
134875d3a19aSMatthew G. Knepley       }
134975d3a19aSMatthew G. Knepley       break;
135075d3a19aSMatthew G. Knepley     case 2:
135175d3a19aSMatthew G. Knepley       /* Hex 2D */
135275d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
135375d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
135475d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
135575d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
135675d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
135775d3a19aSMatthew G. Knepley         ++m;
135875d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
135975d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
136075d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
136175d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
136275d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
136375d3a19aSMatthew G. Knepley         ++m;
136475d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
136575d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
136675d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
136775d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
136875d3a19aSMatthew G. Knepley         }
136975d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
137075d3a19aSMatthew G. Knepley         /* Old cells add new cells and interior faces */
137175d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
137275d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
137375d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
137475d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
137575d3a19aSMatthew G. Knepley         }
137675d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
137775d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*2                    + (p  - cStart)*4     + r;
137875d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r;
137975d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
138075d3a19aSMatthew G. Knepley         }
138175d3a19aSMatthew G. Knepley       }
138275d3a19aSMatthew G. Knepley       break;
138375d3a19aSMatthew G. Knepley     case 3:
138475d3a19aSMatthew G. Knepley       /* Hybrid simplicial 2D */
138575d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
138675d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
138775d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
138875d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
138975d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
139075d3a19aSMatthew G. Knepley         ++m;
139175d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
139275d3a19aSMatthew G. Knepley         /* Old interior faces add new faces and vertex */
139375d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
139475d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
139575d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
139675d3a19aSMatthew G. Knepley         ++m;
139775d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
139875d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
139975d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
140075d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
140175d3a19aSMatthew G. Knepley         }
140275d3a19aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
140375d3a19aSMatthew G. Knepley         /* Old hybrid faces stay the same */
140475d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
140575d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
140675d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
140775d3a19aSMatthew G. Knepley         ++m;
140875d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
140975d3a19aSMatthew G. Knepley         /* Old interior cells add new cells and interior faces */
141075d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
141175d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
141275d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
141375d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
141475d3a19aSMatthew G. Knepley         }
141575d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
141675d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*3     + r;
141775d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r;
141875d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
141975d3a19aSMatthew G. Knepley         }
142075d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
142175d3a19aSMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
142275d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
142375d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
142475d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
142575d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
142675d3a19aSMatthew G. Knepley         }
142775d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*3     + (p  - cMax);
142875d3a19aSMatthew 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]);
142975d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
143075d3a19aSMatthew G. Knepley         ++m;
143175d3a19aSMatthew G. Knepley       }
143275d3a19aSMatthew G. Knepley       break;
143375d3a19aSMatthew G. Knepley     default:
143475d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
143575d3a19aSMatthew G. Knepley     }
143675d3a19aSMatthew G. Knepley   }
143775d3a19aSMatthew G. Knepley   ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr);
143875d3a19aSMatthew G. Knepley   ierr = ISDestroy(&processRanks);CHKERRQ(ierr);
143975d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
144075d3a19aSMatthew G. Knepley   ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr);
144175d3a19aSMatthew G. Knepley   ierr = PetscFree6(depthSizeOld,rdepthSizeOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr);
144275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
144375d3a19aSMatthew G. Knepley }
144475d3a19aSMatthew G. Knepley 
144575d3a19aSMatthew G. Knepley #undef __FUNCT__
144675d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateLabels"
144775d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
144875d3a19aSMatthew G. Knepley {
144975d3a19aSMatthew G. Knepley   PetscInt       numLabels, l;
145075d3a19aSMatthew G. Knepley   PetscInt       newp, cStart, cStartNew, cEnd, cMax, vStart, vStartNew, vEnd, vMax, fStart, fStartNew, fEnd, fMax, eStart, eEnd, eMax, r;
145175d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
145275d3a19aSMatthew G. Knepley 
145375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
145475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
145575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
145675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
145775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
145875d3a19aSMatthew G. Knepley 
145975d3a19aSMatthew G. Knepley   cStartNew = 0;
146075d3a19aSMatthew G. Knepley   vStartNew = depthSize[2];
146175d3a19aSMatthew G. Knepley   fStartNew = depthSize[2] + depthSize[0];
146275d3a19aSMatthew G. Knepley 
146375d3a19aSMatthew G. Knepley   ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr);
146475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
146575d3a19aSMatthew G. Knepley   switch (refiner) {
146675d3a19aSMatthew G. Knepley   case 3:
146775d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
146875d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
146975d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
147075d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
147175d3a19aSMatthew G. Knepley   }
147275d3a19aSMatthew G. Knepley   for (l = 0; l < numLabels; ++l) {
147375d3a19aSMatthew G. Knepley     DMLabel         label, labelNew;
147475d3a19aSMatthew G. Knepley     const char     *lname;
147575d3a19aSMatthew G. Knepley     PetscBool       isDepth;
147675d3a19aSMatthew G. Knepley     IS              valueIS;
147775d3a19aSMatthew G. Knepley     const PetscInt *values;
147875d3a19aSMatthew G. Knepley     PetscInt        numValues, val;
147975d3a19aSMatthew G. Knepley 
148075d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr);
148175d3a19aSMatthew G. Knepley     ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr);
148275d3a19aSMatthew G. Knepley     if (isDepth) continue;
148375d3a19aSMatthew G. Knepley     ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr);
148475d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr);
148575d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr);
148675d3a19aSMatthew G. Knepley     ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr);
148775d3a19aSMatthew G. Knepley     ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr);
148875d3a19aSMatthew G. Knepley     ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr);
148975d3a19aSMatthew G. Knepley     for (val = 0; val < numValues; ++val) {
149075d3a19aSMatthew G. Knepley       IS              pointIS;
149175d3a19aSMatthew G. Knepley       const PetscInt *points;
149275d3a19aSMatthew G. Knepley       PetscInt        numPoints, n;
149375d3a19aSMatthew G. Knepley 
149475d3a19aSMatthew G. Knepley       ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr);
149575d3a19aSMatthew G. Knepley       ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);
149675d3a19aSMatthew G. Knepley       ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr);
149775d3a19aSMatthew G. Knepley       for (n = 0; n < numPoints; ++n) {
149875d3a19aSMatthew G. Knepley         const PetscInt p = points[n];
149975d3a19aSMatthew G. Knepley         switch (refiner) {
150075d3a19aSMatthew G. Knepley         case 1:
150175d3a19aSMatthew G. Knepley           /* Simplicial 2D */
150275d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
150375d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
150475d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
150575d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
150675d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
150775d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
150875d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
150975d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
151075d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
151175d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
151275d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
151375d3a19aSMatthew G. Knepley             }
151475d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
151575d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces */
151675d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
151775d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
151875d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
151975d3a19aSMatthew G. Knepley             }
152075d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
152175d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
152275d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
152375d3a19aSMatthew G. Knepley             }
152475d3a19aSMatthew G. Knepley           }
152575d3a19aSMatthew G. Knepley           break;
152675d3a19aSMatthew G. Knepley         case 2:
152775d3a19aSMatthew G. Knepley           /* Hex 2D */
152875d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
152975d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
153075d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
153175d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
153275d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
153375d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
153475d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
153575d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
153675d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
153775d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
153875d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
153975d3a19aSMatthew G. Knepley             }
154075d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
154175d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces and vertex */
154275d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
154375d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
154475d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
154575d3a19aSMatthew G. Knepley             }
154675d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
154775d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
154875d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
154975d3a19aSMatthew G. Knepley             }
155075d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
155175d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
155275d3a19aSMatthew G. Knepley           }
155375d3a19aSMatthew G. Knepley           break;
155475d3a19aSMatthew G. Knepley         case 3:
155575d3a19aSMatthew G. Knepley           /* Hybrid simplicial 2D */
155675d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
155775d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
155875d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
155975d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
156075d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
156175d3a19aSMatthew G. Knepley             /* Old interior faces add new faces and vertex */
156275d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
156375d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
156475d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
156575d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
156675d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
156775d3a19aSMatthew G. Knepley             }
156875d3a19aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
156975d3a19aSMatthew G. Knepley             /* Old hybrid faces stay the same */
157075d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
157175d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
157275d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
157375d3a19aSMatthew G. Knepley             /* Old interior cells add new cells and interior faces */
157475d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
157575d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
157675d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
157775d3a19aSMatthew G. Knepley             }
157875d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
157975d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
158075d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
158175d3a19aSMatthew G. Knepley             }
158275d3a19aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
158375d3a19aSMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
158475d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
158575d3a19aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
158675d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
158775d3a19aSMatthew G. Knepley             }
158875d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
158975d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
159075d3a19aSMatthew G. Knepley           }
159175d3a19aSMatthew G. Knepley           break;
159275d3a19aSMatthew G. Knepley         default:
159375d3a19aSMatthew G. Knepley           SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
159475d3a19aSMatthew G. Knepley         }
159575d3a19aSMatthew G. Knepley       }
159675d3a19aSMatthew G. Knepley       ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr);
159775d3a19aSMatthew G. Knepley       ierr = ISDestroy(&pointIS);CHKERRQ(ierr);
159875d3a19aSMatthew G. Knepley     }
159975d3a19aSMatthew G. Knepley     ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr);
160075d3a19aSMatthew G. Knepley     ierr = ISDestroy(&valueIS);CHKERRQ(ierr);
160175d3a19aSMatthew G. Knepley     if (0) {
160275d3a19aSMatthew G. Knepley       ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr);
160375d3a19aSMatthew G. Knepley       ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
160475d3a19aSMatthew G. Knepley       ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
160575d3a19aSMatthew G. Knepley     }
160675d3a19aSMatthew G. Knepley   }
160775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
160875d3a19aSMatthew G. Knepley }
160975d3a19aSMatthew G. Knepley 
161075d3a19aSMatthew G. Knepley #undef __FUNCT__
1611*509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexRefineUniform_Internal"
161275d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */
1613*509c9b89SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined)
161475d3a19aSMatthew G. Knepley {
161575d3a19aSMatthew G. Knepley   DM             rdm;
161675d3a19aSMatthew G. Knepley   PetscInt      *depthSize;
161775d3a19aSMatthew G. Knepley   PetscInt       dim, depth = 0, d, pStart = 0, pEnd = 0;
161875d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
161975d3a19aSMatthew G. Knepley 
162075d3a19aSMatthew G. Knepley   PetscFunctionBegin;
162175d3a19aSMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr);
162275d3a19aSMatthew G. Knepley   ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr);
162375d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
162475d3a19aSMatthew G. Knepley   ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr);
162575d3a19aSMatthew G. Knepley   /* Calculate number of new points of each depth */
162675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
162775d3a19aSMatthew G. Knepley   ierr = PetscMalloc((depth+1) * sizeof(PetscInt), &depthSize);CHKERRQ(ierr);
162875d3a19aSMatthew G. Knepley   ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr);
162975d3a19aSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
163075d3a19aSMatthew G. Knepley   /* Step 1: Set chart */
163175d3a19aSMatthew G. Knepley   for (d = 0; d <= depth; ++d) pEnd += depthSize[d];
163275d3a19aSMatthew G. Knepley   ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr);
163375d3a19aSMatthew G. Knepley   /* Step 2: Set cone/support sizes */
163475d3a19aSMatthew G. Knepley   ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
163575d3a19aSMatthew G. Knepley   /* Step 3: Setup refined DM */
163675d3a19aSMatthew G. Knepley   ierr = DMSetUp(rdm);CHKERRQ(ierr);
163775d3a19aSMatthew G. Knepley   /* Step 4: Set cones and supports */
163875d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
163975d3a19aSMatthew G. Knepley   /* Step 5: Stratify */
164075d3a19aSMatthew G. Knepley   ierr = DMPlexStratify(rdm);CHKERRQ(ierr);
164175d3a19aSMatthew G. Knepley   /* Step 6: Set coordinates for vertices */
164275d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
164375d3a19aSMatthew G. Knepley   /* Step 7: Create pointSF */
164475d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
164575d3a19aSMatthew G. Knepley   /* Step 8: Create labels */
164675d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
164775d3a19aSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
164875d3a19aSMatthew G. Knepley 
164975d3a19aSMatthew G. Knepley   *dmRefined = rdm;
165075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
165175d3a19aSMatthew G. Knepley }
165275d3a19aSMatthew G. Knepley 
165375d3a19aSMatthew G. Knepley #undef __FUNCT__
165475d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementUniform"
165575d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
165675d3a19aSMatthew G. Knepley {
165775d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
165875d3a19aSMatthew G. Knepley 
165975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
166075d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
166175d3a19aSMatthew G. Knepley   mesh->refinementUniform = refinementUniform;
166275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
166375d3a19aSMatthew G. Knepley }
166475d3a19aSMatthew G. Knepley 
166575d3a19aSMatthew G. Knepley #undef __FUNCT__
166675d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementUniform"
166775d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
166875d3a19aSMatthew G. Knepley {
166975d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
167075d3a19aSMatthew G. Knepley 
167175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
167275d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
167375d3a19aSMatthew G. Knepley   PetscValidPointer(refinementUniform,  2);
167475d3a19aSMatthew G. Knepley   *refinementUniform = mesh->refinementUniform;
167575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
167675d3a19aSMatthew G. Knepley }
167775d3a19aSMatthew G. Knepley 
167875d3a19aSMatthew G. Knepley #undef __FUNCT__
167975d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementLimit"
168075d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
168175d3a19aSMatthew G. Knepley {
168275d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
168375d3a19aSMatthew G. Knepley 
168475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
168575d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
168675d3a19aSMatthew G. Knepley   mesh->refinementLimit = refinementLimit;
168775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
168875d3a19aSMatthew G. Knepley }
168975d3a19aSMatthew G. Knepley 
169075d3a19aSMatthew G. Knepley #undef __FUNCT__
169175d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementLimit"
169275d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
169375d3a19aSMatthew G. Knepley {
169475d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
169575d3a19aSMatthew G. Knepley 
169675d3a19aSMatthew G. Knepley   PetscFunctionBegin;
169775d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
169875d3a19aSMatthew G. Knepley   PetscValidPointer(refinementLimit,  2);
169975d3a19aSMatthew G. Knepley   /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
170075d3a19aSMatthew G. Knepley   *refinementLimit = mesh->refinementLimit;
170175d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
170275d3a19aSMatthew G. Knepley }
170375d3a19aSMatthew G. Knepley 
170475d3a19aSMatthew G. Knepley #undef __FUNCT__
1705*509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexGetCellRefiner_Internal"
1706*509c9b89SMatthew G. Knepley PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner)
170775d3a19aSMatthew G. Knepley {
170875d3a19aSMatthew G. Knepley   PetscInt       dim, cStart, coneSize, cMax;
170975d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
171075d3a19aSMatthew G. Knepley 
171175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
171275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
171375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, NULL);CHKERRQ(ierr);
171475d3a19aSMatthew G. Knepley   ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr);
171575d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr);
171675d3a19aSMatthew G. Knepley   switch (dim) {
171775d3a19aSMatthew G. Knepley   case 2:
171875d3a19aSMatthew G. Knepley     switch (coneSize) {
171975d3a19aSMatthew G. Knepley     case 3:
172075d3a19aSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 3; /* Hybrid */
172175d3a19aSMatthew G. Knepley       else *cellRefiner = 1; /* Triangular */
172275d3a19aSMatthew G. Knepley       break;
172375d3a19aSMatthew G. Knepley     case 4:
172475d3a19aSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 4; /* Hybrid */
172575d3a19aSMatthew G. Knepley       else *cellRefiner = 2; /* Quadrilateral */
172675d3a19aSMatthew G. Knepley       break;
172775d3a19aSMatthew G. Knepley     default:
172875d3a19aSMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
172975d3a19aSMatthew G. Knepley     }
173075d3a19aSMatthew G. Knepley     break;
173175d3a19aSMatthew G. Knepley   default:
173275d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim);
173375d3a19aSMatthew G. Knepley   }
173475d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
173575d3a19aSMatthew G. Knepley }
1736