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__ 29*b5da9499SMatthew G. Knepley #define __FUNCT__ "DMPlexGetNumHybridFaces_Internal" 30*b5da9499SMatthew G. Knepley /* This is a stopgap since we do not currently keep track of faces for hybrid cells */ 31*b5da9499SMatthew G. Knepley static PetscErrorCode DMPlexGetNumHybridFaces_Internal(DM dm, PetscInt *numHybridFaces) 32*b5da9499SMatthew G. Knepley { 33*b5da9499SMatthew G. Knepley PetscInt eStart, eEnd, eMax, cEnd, cMax, c, hEdges = 0; 34*b5da9499SMatthew G. Knepley PetscErrorCode ierr; 35*b5da9499SMatthew G. Knepley 36*b5da9499SMatthew G. Knepley PetscFunctionBegin; 37*b5da9499SMatthew G. Knepley *numHybridFaces = 0; 38*b5da9499SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 39*b5da9499SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, NULL, &cEnd);CHKERRQ(ierr); 40*b5da9499SMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, &eMax, NULL);CHKERRQ(ierr); 41*b5da9499SMatthew G. Knepley if (cMax < 0) PetscFunctionReturn(0); 42*b5da9499SMatthew G. Knepley /* Count interior edges in hybrid cells */ 43*b5da9499SMatthew G. Knepley for (c = cMax; c < cEnd; ++c) { 44*b5da9499SMatthew G. Knepley PetscInt *closure = NULL, closureSize, cl; 45*b5da9499SMatthew G. Knepley 46*b5da9499SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 47*b5da9499SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 48*b5da9499SMatthew G. Knepley const PetscInt p = closure[cl]; 49*b5da9499SMatthew G. Knepley 50*b5da9499SMatthew G. Knepley if ((p >= eStart) && (p < eMax)) ++hEdges; 51*b5da9499SMatthew G. Knepley } 52*b5da9499SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 53*b5da9499SMatthew G. Knepley } 54*b5da9499SMatthew G. Knepley if (hEdges%2) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Number of interior edges in hybrid cells cannot be odd: %d", hEdges); 55*b5da9499SMatthew G. Knepley *numHybridFaces = hEdges/2; 56*b5da9499SMatthew G. Knepley PetscFunctionReturn(0); 57*b5da9499SMatthew G. Knepley } 58*b5da9499SMatthew G. Knepley 59*b5da9499SMatthew G. Knepley #undef __FUNCT__ 6075d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerGetSizes" 6175d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[]) 6275d3a19aSMatthew G. Knepley { 63*b5da9499SMatthew G. Knepley PetscInt numHybridFaces, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 6475d3a19aSMatthew G. Knepley PetscErrorCode ierr; 6575d3a19aSMatthew G. Knepley 6675d3a19aSMatthew G. Knepley PetscFunctionBegin; 6775d3a19aSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6875d3a19aSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 6975d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 7075d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 7175d3a19aSMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 7275d3a19aSMatthew G. Knepley switch (refiner) { 7375d3a19aSMatthew G. Knepley case 1: 7475d3a19aSMatthew G. Knepley /* Simplicial 2D */ 7575d3a19aSMatthew G. Knepley depthSize[0] = vEnd - vStart + fEnd - fStart; /* Add a vertex on every face */ 7675d3a19aSMatthew 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 */ 7775d3a19aSMatthew G. Knepley depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 7875d3a19aSMatthew G. Knepley break; 7975d3a19aSMatthew G. Knepley case 3: 80d963de37SMatthew G. Knepley /* Hybrid Simplicial 2D */ 8175d3a19aSMatthew G. Knepley if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 8275d3a19aSMatthew G. Knepley cMax = PetscMin(cEnd, cMax); 8375d3a19aSMatthew G. Knepley if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 8475d3a19aSMatthew G. Knepley fMax = PetscMin(fEnd, fMax); 8575d3a19aSMatthew G. Knepley depthSize[0] = vEnd - vStart + fMax - fStart; /* Add a vertex on every face, but not hybrid faces */ 8675d3a19aSMatthew 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 */ 8775d3a19aSMatthew G. Knepley depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax); /* Interior cells split into 4 cells, Hybrid cells split into 2 cells */ 8875d3a19aSMatthew G. Knepley break; 8975d3a19aSMatthew G. Knepley case 2: 9075d3a19aSMatthew G. Knepley /* Hex 2D */ 9175d3a19aSMatthew G. Knepley depthSize[0] = vEnd - vStart + cEnd - cStart + fEnd - fStart; /* Add a vertex on every face and cell */ 9275d3a19aSMatthew 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 */ 9375d3a19aSMatthew G. Knepley depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 9475d3a19aSMatthew G. Knepley break; 95*b5da9499SMatthew G. Knepley case 5: 96*b5da9499SMatthew G. Knepley /* Simplicial 3D */ 97*b5da9499SMatthew G. Knepley depthSize[0] = vEnd - vStart + eEnd - eStart; /* Add a vertex on every edge */ 98*b5da9499SMatthew G. Knepley depthSize[1] = 2*(eEnd - eStart) + 3*(fEnd - fStart) + (cEnd - cStart); /* Every edge is split into 2 edges, 3 edges are added for each face, and 1 edge for each cell */ 99*b5da9499SMatthew G. Knepley depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart); /* Every face split into 4 faces and 8 faces are added for each cell */ 100*b5da9499SMatthew G. Knepley depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 101*b5da9499SMatthew G. Knepley break; 102*b5da9499SMatthew G. Knepley case 7: 103*b5da9499SMatthew G. Knepley /* Hybrid Simplicial 3D */ 104*b5da9499SMatthew G. Knepley ierr = DMPlexGetNumHybridFaces_Internal(dm, &numHybridFaces);CHKERRQ(ierr); 105*b5da9499SMatthew G. Knepley if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 106*b5da9499SMatthew G. Knepley cMax = PetscMin(cEnd, cMax); 107*b5da9499SMatthew G. Knepley if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 108*b5da9499SMatthew G. Knepley eMax = PetscMin(eEnd, eMax); 109*b5da9499SMatthew G. Knepley depthSize[0] = vEnd - vStart + eMax - eStart; /* Add a vertex on every edge, but not hybrid edges */ 110*b5da9499SMatthew G. Knepley depthSize[1] = 2*(eMax - eStart) + 13*(cMax - cStart) + (eEnd - eMax) + numHybridFaces; /* Every interior edge is split into 2 edges and 13 edges are added for each interior cell, each hybrid edge stays intact, and one new hybrid edge for each two interior edges (hybrid face) on a hybrid cell */ 111*b5da9499SMatthew G. Knepley depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart); /* Every face split into 4 faces and 8 faces are added for each cell */ 112*b5da9499SMatthew G. Knepley depthSize[3] = 8*(cMax - cStart) + 4*(cEnd - cMax); /* Every interior cell split into 8 cells, and every hybrid cell split into 4 cells */ 113*b5da9499SMatthew G. Knepley break; 11475d3a19aSMatthew G. Knepley default: 11575d3a19aSMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 11675d3a19aSMatthew G. Knepley } 11775d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 11875d3a19aSMatthew G. Knepley } 11975d3a19aSMatthew G. Knepley 12075d3a19aSMatthew G. Knepley #undef __FUNCT__ 12175d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetConeSizes" 12275d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 12375d3a19aSMatthew G. Knepley { 124*b5da9499SMatthew G. Knepley PetscInt depth, cStart, cStartNew, cEnd, cMax, c, vStart, vStartNew, vEnd, vMax, v, fStart, fStartNew, fEnd, fMax, f, eStart, eStartNew, eEnd, eMax, e, r; 12575d3a19aSMatthew G. Knepley PetscErrorCode ierr; 12675d3a19aSMatthew G. Knepley 12775d3a19aSMatthew G. Knepley PetscFunctionBegin; 12875d3a19aSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 12975d3a19aSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 13075d3a19aSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 13175d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 13275d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 13375d3a19aSMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 13475d3a19aSMatthew G. Knepley ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 13575d3a19aSMatthew G. Knepley switch (refiner) { 13675d3a19aSMatthew G. Knepley case 1: 13775d3a19aSMatthew G. Knepley /* Simplicial 2D */ 13875d3a19aSMatthew G. Knepley /* All cells have 3 faces */ 13975d3a19aSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 14075d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r) { 14175d3a19aSMatthew G. Knepley const PetscInt newp = (c - cStart)*4 + r; 14275d3a19aSMatthew G. Knepley 14375d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 14475d3a19aSMatthew G. Knepley } 14575d3a19aSMatthew G. Knepley } 14675d3a19aSMatthew G. Knepley /* Split faces have 2 vertices and the same cells as the parent */ 14775d3a19aSMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 14875d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 14975d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (f - fStart)*2 + r; 15075d3a19aSMatthew G. Knepley PetscInt size; 15175d3a19aSMatthew G. Knepley 15275d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 15375d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 15475d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 15575d3a19aSMatthew G. Knepley } 15675d3a19aSMatthew G. Knepley } 15775d3a19aSMatthew G. Knepley /* Interior faces have 2 vertices and 2 cells */ 15875d3a19aSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 15975d3a19aSMatthew G. Knepley for (r = 0; r < 3; ++r) { 16075d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 16175d3a19aSMatthew G. Knepley 16275d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 16375d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 16475d3a19aSMatthew G. Knepley } 16575d3a19aSMatthew G. Knepley } 16675d3a19aSMatthew G. Knepley /* Old vertices have identical supports */ 16775d3a19aSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 16875d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (v - vStart); 16975d3a19aSMatthew G. Knepley PetscInt size; 17075d3a19aSMatthew G. Knepley 17175d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 17275d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 17375d3a19aSMatthew G. Knepley } 17475d3a19aSMatthew G. Knepley /* Face vertices have 2 + cells*2 supports */ 17575d3a19aSMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 17675d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 17775d3a19aSMatthew G. Knepley PetscInt size; 17875d3a19aSMatthew G. Knepley 17975d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 18075d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr); 18175d3a19aSMatthew G. Knepley } 18275d3a19aSMatthew G. Knepley break; 18375d3a19aSMatthew G. Knepley case 2: 18475d3a19aSMatthew G. Knepley /* Hex 2D */ 18575d3a19aSMatthew G. Knepley /* All cells have 4 faces */ 18675d3a19aSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 18775d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r) { 18875d3a19aSMatthew G. Knepley const PetscInt newp = (c - cStart)*4 + r; 18975d3a19aSMatthew G. Knepley 19075d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 19175d3a19aSMatthew G. Knepley } 19275d3a19aSMatthew G. Knepley } 19375d3a19aSMatthew G. Knepley /* Split faces have 2 vertices and the same cells as the parent */ 19475d3a19aSMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 19575d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 19675d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (f - fStart)*2 + r; 19775d3a19aSMatthew G. Knepley PetscInt size; 19875d3a19aSMatthew G. Knepley 19975d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 20075d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 20175d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 20275d3a19aSMatthew G. Knepley } 20375d3a19aSMatthew G. Knepley } 20475d3a19aSMatthew G. Knepley /* Interior faces have 2 vertices and 2 cells */ 20575d3a19aSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 20675d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r) { 20775d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 20875d3a19aSMatthew G. Knepley 20975d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 21075d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 21175d3a19aSMatthew G. Knepley } 21275d3a19aSMatthew G. Knepley } 21375d3a19aSMatthew G. Knepley /* Old vertices have identical supports */ 21475d3a19aSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 21575d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (v - vStart); 21675d3a19aSMatthew G. Knepley PetscInt size; 21775d3a19aSMatthew G. Knepley 21875d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 21975d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 22075d3a19aSMatthew G. Knepley } 22175d3a19aSMatthew G. Knepley /* Face vertices have 2 + cells supports */ 22275d3a19aSMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 22375d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 22475d3a19aSMatthew G. Knepley PetscInt size; 22575d3a19aSMatthew G. Knepley 22675d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 22775d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 22875d3a19aSMatthew G. Knepley } 22975d3a19aSMatthew G. Knepley /* Cell vertices have 4 supports */ 23075d3a19aSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 23175d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 23275d3a19aSMatthew G. Knepley 23375d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 23475d3a19aSMatthew G. Knepley } 23575d3a19aSMatthew G. Knepley break; 23675d3a19aSMatthew G. Knepley case 3: 237d963de37SMatthew G. Knepley /* Hybrid Simplicial 2D */ 23875d3a19aSMatthew G. Knepley if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 23975d3a19aSMatthew G. Knepley cMax = PetscMin(cEnd, cMax); 24075d3a19aSMatthew G. Knepley if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 24175d3a19aSMatthew G. Knepley fMax = PetscMin(fEnd, fMax); 24275d3a19aSMatthew G. Knepley ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 24375d3a19aSMatthew G. Knepley /* Interior cells have 3 faces */ 24475d3a19aSMatthew G. Knepley for (c = cStart; c < cMax; ++c) { 24575d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r) { 24675d3a19aSMatthew G. Knepley const PetscInt newp = cStartNew + (c - cStart)*4 + r; 24775d3a19aSMatthew G. Knepley 24875d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 24975d3a19aSMatthew G. Knepley } 25075d3a19aSMatthew G. Knepley } 25175d3a19aSMatthew G. Knepley /* Hybrid cells have 4 faces */ 25275d3a19aSMatthew G. Knepley for (c = cMax; c < cEnd; ++c) { 25375d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 25475d3a19aSMatthew G. Knepley const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 25575d3a19aSMatthew G. Knepley 25675d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 25775d3a19aSMatthew G. Knepley } 25875d3a19aSMatthew G. Knepley } 25975d3a19aSMatthew G. Knepley /* Interior split faces have 2 vertices and the same cells as the parent */ 26075d3a19aSMatthew G. Knepley for (f = fStart; f < fMax; ++f) { 26175d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 26275d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (f - fStart)*2 + r; 26375d3a19aSMatthew G. Knepley PetscInt size; 26475d3a19aSMatthew G. Knepley 26575d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 26675d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 26775d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 26875d3a19aSMatthew G. Knepley } 26975d3a19aSMatthew G. Knepley } 27075d3a19aSMatthew G. Knepley /* Interior cell faces have 2 vertices and 2 cells */ 27175d3a19aSMatthew G. Knepley for (c = cStart; c < cMax; ++c) { 27275d3a19aSMatthew G. Knepley for (r = 0; r < 3; ++r) { 27375d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 27475d3a19aSMatthew G. Knepley 27575d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 27675d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 27775d3a19aSMatthew G. Knepley } 27875d3a19aSMatthew G. Knepley } 27975d3a19aSMatthew G. Knepley /* Hybrid faces have 2 vertices and the same cells */ 28075d3a19aSMatthew G. Knepley for (f = fMax; f < fEnd; ++f) { 28175d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 28275d3a19aSMatthew G. Knepley PetscInt size; 28375d3a19aSMatthew G. Knepley 28475d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 28575d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 28675d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 28775d3a19aSMatthew G. Knepley } 28875d3a19aSMatthew G. Knepley /* Hybrid cell faces have 2 vertices and 2 cells */ 28975d3a19aSMatthew G. Knepley for (c = cMax; c < cEnd; ++c) { 29075d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 29175d3a19aSMatthew G. Knepley 29275d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 29375d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 29475d3a19aSMatthew G. Knepley } 29575d3a19aSMatthew G. Knepley /* Old vertices have identical supports */ 29675d3a19aSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 29775d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (v - vStart); 29875d3a19aSMatthew G. Knepley PetscInt size; 29975d3a19aSMatthew G. Knepley 30075d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 30175d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 30275d3a19aSMatthew G. Knepley } 30375d3a19aSMatthew G. Knepley /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 30475d3a19aSMatthew G. Knepley for (f = fStart; f < fMax; ++f) { 30575d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 30675d3a19aSMatthew G. Knepley const PetscInt *support; 30775d3a19aSMatthew G. Knepley PetscInt size, newSize = 2, s; 30875d3a19aSMatthew G. Knepley 30975d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 31075d3a19aSMatthew G. Knepley ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 31175d3a19aSMatthew G. Knepley for (s = 0; s < size; ++s) { 31275d3a19aSMatthew G. Knepley if (support[s] >= cMax) newSize += 1; 31375d3a19aSMatthew G. Knepley else newSize += 2; 31475d3a19aSMatthew G. Knepley } 31575d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr); 31675d3a19aSMatthew G. Knepley } 31775d3a19aSMatthew G. Knepley break; 318*b5da9499SMatthew G. Knepley case 5: 319*b5da9499SMatthew G. Knepley /* Simplicial 3D */ 320*b5da9499SMatthew G. Knepley /* All cells have 4 faces */ 321*b5da9499SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 322*b5da9499SMatthew G. Knepley for (r = 0; r < 8; ++r) { 323*b5da9499SMatthew G. Knepley const PetscInt newp = (c - cStart)*8 + r; 324*b5da9499SMatthew G. Knepley 325*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 326*b5da9499SMatthew G. Knepley } 327*b5da9499SMatthew G. Knepley } 328*b5da9499SMatthew G. Knepley /* Split faces have 3 edges and the same cells as the parent */ 329*b5da9499SMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 330*b5da9499SMatthew G. Knepley for (r = 0; r < 4; ++r) { 331*b5da9499SMatthew G. Knepley const PetscInt newp = fStartNew + (f - fStart)*4 + r; 332*b5da9499SMatthew G. Knepley PetscInt size; 333*b5da9499SMatthew G. Knepley 334*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 335*b5da9499SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 336*b5da9499SMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 337*b5da9499SMatthew G. Knepley } 338*b5da9499SMatthew G. Knepley } 339*b5da9499SMatthew G. Knepley /* Interior faces have 3 edges and 2 cells */ 340*b5da9499SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 341*b5da9499SMatthew G. Knepley for (r = 0; r < 8; ++r) { 342*b5da9499SMatthew G. Knepley const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r; 343*b5da9499SMatthew G. Knepley 344*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 345*b5da9499SMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 346*b5da9499SMatthew G. Knepley } 347*b5da9499SMatthew G. Knepley } 348*b5da9499SMatthew G. Knepley /* Split edges have 2 vertices and the same faces */ 349*b5da9499SMatthew G. Knepley for (e = eStart; e < eEnd; ++e) { 350*b5da9499SMatthew G. Knepley for (r = 0; r < 2; ++r) { 351*b5da9499SMatthew G. Knepley const PetscInt newp = eStartNew + (e - eStart)*2 + r; 352*b5da9499SMatthew G. Knepley PetscInt size; 353*b5da9499SMatthew G. Knepley 354*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 355*b5da9499SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 356*b5da9499SMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 357*b5da9499SMatthew G. Knepley } 358*b5da9499SMatthew G. Knepley } 359*b5da9499SMatthew G. Knepley /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 360*b5da9499SMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 361*b5da9499SMatthew G. Knepley for (r = 0; r < 3; ++r) { 362*b5da9499SMatthew G. Knepley const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 363*b5da9499SMatthew G. Knepley const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 364*b5da9499SMatthew G. Knepley PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 365*b5da9499SMatthew G. Knepley 366*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 367*b5da9499SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 368*b5da9499SMatthew G. Knepley ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 369*b5da9499SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 370*b5da9499SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 371*b5da9499SMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 372*b5da9499SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 373*b5da9499SMatthew G. Knepley for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 374*b5da9499SMatthew G. Knepley WRONG er = ornt[c] < 0 ? (-(ornt[c]+1) + r)%3 : (ornt[c] + r)%3; 375*b5da9499SMatthew G. Knepley if (er == eint[c]) { 376*b5da9499SMatthew G. Knepley intFaces += 1; 377*b5da9499SMatthew G. Knepley } else { 378*b5da9499SMatthew G. Knepley intFaces += 2; 379*b5da9499SMatthew G. Knepley } 380*b5da9499SMatthew G. Knepley } 381*b5da9499SMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 382*b5da9499SMatthew G. Knepley } 383*b5da9499SMatthew G. Knepley } 384*b5da9499SMatthew G. Knepley /* Interior edges have 2 vertices and 4 faces */ 385*b5da9499SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 386*b5da9499SMatthew G. Knepley const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 387*b5da9499SMatthew G. Knepley 388*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 389*b5da9499SMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 390*b5da9499SMatthew G. Knepley } 391*b5da9499SMatthew G. Knepley /* Old vertices have identical supports */ 392*b5da9499SMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 393*b5da9499SMatthew G. Knepley const PetscInt newp = vStartNew + (v - vStart); 394*b5da9499SMatthew G. Knepley PetscInt size; 395*b5da9499SMatthew G. Knepley 396*b5da9499SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 397*b5da9499SMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 398*b5da9499SMatthew G. Knepley } 399*b5da9499SMatthew G. Knepley /* Edge vertices have 2 + faces*2 + cells*0/1 supports */ 400*b5da9499SMatthew G. Knepley for (e = eStart; e < eEnd; ++e) { 401*b5da9499SMatthew G. Knepley const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 402*b5da9499SMatthew G. Knepley PetscInt size, *star = NULL, starSize, s, cellSize = 0; 403*b5da9499SMatthew G. Knepley 404*b5da9499SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 405*b5da9499SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 406*b5da9499SMatthew G. Knepley for (s = 0; s < starSize*2; s += 2) { 407*b5da9499SMatthew G. Knepley const PetscInt *cone, *ornt; 408*b5da9499SMatthew G. Knepley PetscInt e01, e23; 409*b5da9499SMatthew G. Knepley 410*b5da9499SMatthew G. Knepley if ((star[s] >= cStart) && (star[s] < cEnd)) { 411*b5da9499SMatthew G. Knepley /* Check edge 0-1 */ 412*b5da9499SMatthew G. Knepley ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 413*b5da9499SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 414*b5da9499SMatthew G. Knepley ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 415*b5da9499SMatthew G. Knepley e01 = cone[ornt[0] < 0 ? (-(ornt[0]+1) + 0)%3 : ornt[0]]; 416*b5da9499SMatthew G. Knepley /* Check edge 2-3 */ 417*b5da9499SMatthew G. Knepley ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 418*b5da9499SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 419*b5da9499SMatthew G. Knepley ierr = DMPlexGetCone(dm, cone[3], &cone);CHKERRQ(ierr); 420*b5da9499SMatthew G. Knepley e23 = cone[ornt[3] < 0 ? (-(ornt[3]+1) + 2)%3 : (ornt[3] + 2)%3]; 421*b5da9499SMatthew G. Knepley if ((e01 == e) || (e23 == e)) ++cellSize; 422*b5da9499SMatthew G. Knepley } 423*b5da9499SMatthew G. Knepley } 424*b5da9499SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 425*b5da9499SMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr); 426*b5da9499SMatthew G. Knepley } 427*b5da9499SMatthew G. Knepley break; 42875d3a19aSMatthew G. Knepley default: 42975d3a19aSMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 43075d3a19aSMatthew G. Knepley } 43175d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 43275d3a19aSMatthew G. Knepley } 43375d3a19aSMatthew G. Knepley 43475d3a19aSMatthew G. Knepley #undef __FUNCT__ 43575d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCones" 43675d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 43775d3a19aSMatthew G. Knepley { 438*b5da9499SMatthew G. Knepley const PetscInt *faces, cellInd[4] = {0, 1, 2, 3}; 439*b5da9499SMatthew 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, e, r, p; 44075d3a19aSMatthew G. Knepley PetscInt maxSupportSize, *supportRef; 44175d3a19aSMatthew G. Knepley PetscErrorCode ierr; 44275d3a19aSMatthew G. Knepley 44375d3a19aSMatthew G. Knepley PetscFunctionBegin; 44475d3a19aSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 44575d3a19aSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 44675d3a19aSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 44775d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 44875d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 44975d3a19aSMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 45075d3a19aSMatthew G. Knepley ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 45175d3a19aSMatthew G. Knepley ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 45275d3a19aSMatthew G. Knepley switch (refiner) { 45375d3a19aSMatthew G. Knepley case 1: 45475d3a19aSMatthew G. Knepley /* Simplicial 2D */ 45575d3a19aSMatthew G. Knepley /* 45675d3a19aSMatthew G. Knepley 2 45775d3a19aSMatthew G. Knepley |\ 45875d3a19aSMatthew G. Knepley | \ 45975d3a19aSMatthew G. Knepley | \ 46075d3a19aSMatthew G. Knepley | \ 46175d3a19aSMatthew G. Knepley | C \ 46275d3a19aSMatthew G. Knepley | \ 46375d3a19aSMatthew G. Knepley | \ 46475d3a19aSMatthew G. Knepley 2---1---1 46575d3a19aSMatthew G. Knepley |\ D / \ 46675d3a19aSMatthew G. Knepley | 2 0 \ 46775d3a19aSMatthew G. Knepley |A \ / B \ 46875d3a19aSMatthew G. Knepley 0---0-------1 46975d3a19aSMatthew G. Knepley */ 47075d3a19aSMatthew G. Knepley /* All cells have 3 faces */ 47175d3a19aSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 47275d3a19aSMatthew G. Knepley const PetscInt newp = cStartNew + (c - cStart)*4; 47375d3a19aSMatthew G. Knepley const PetscInt *cone, *ornt; 47475d3a19aSMatthew G. Knepley PetscInt coneNew[3], orntNew[3]; 47575d3a19aSMatthew G. Knepley 47675d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 47775d3a19aSMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 47875d3a19aSMatthew G. Knepley /* A triangle */ 47975d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 48075d3a19aSMatthew G. Knepley orntNew[0] = ornt[0]; 48175d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 48275d3a19aSMatthew G. Knepley orntNew[1] = -2; 48375d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 48475d3a19aSMatthew G. Knepley orntNew[2] = ornt[2]; 48575d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 48675d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 48775d3a19aSMatthew G. Knepley #if 1 48875d3a19aSMatthew 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); 48975d3a19aSMatthew G. Knepley for (p = 0; p < 3; ++p) { 49075d3a19aSMatthew 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); 49175d3a19aSMatthew G. Knepley } 49275d3a19aSMatthew G. Knepley #endif 49375d3a19aSMatthew G. Knepley /* B triangle */ 49475d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 49575d3a19aSMatthew G. Knepley orntNew[0] = ornt[0]; 49675d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 49775d3a19aSMatthew G. Knepley orntNew[1] = ornt[1]; 49875d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 49975d3a19aSMatthew G. Knepley orntNew[2] = -2; 50075d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 50175d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 50275d3a19aSMatthew G. Knepley #if 1 50375d3a19aSMatthew 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); 50475d3a19aSMatthew G. Knepley for (p = 0; p < 3; ++p) { 50575d3a19aSMatthew 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); 50675d3a19aSMatthew G. Knepley } 50775d3a19aSMatthew G. Knepley #endif 50875d3a19aSMatthew G. Knepley /* C triangle */ 50975d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 51075d3a19aSMatthew G. Knepley orntNew[0] = -2; 51175d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 51275d3a19aSMatthew G. Knepley orntNew[1] = ornt[1]; 51375d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 51475d3a19aSMatthew G. Knepley orntNew[2] = ornt[2]; 51575d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 51675d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 51775d3a19aSMatthew G. Knepley #if 1 51875d3a19aSMatthew 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); 51975d3a19aSMatthew G. Knepley for (p = 0; p < 3; ++p) { 52075d3a19aSMatthew 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); 52175d3a19aSMatthew G. Knepley } 52275d3a19aSMatthew G. Knepley #endif 52375d3a19aSMatthew G. Knepley /* D triangle */ 52475d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 52575d3a19aSMatthew G. Knepley orntNew[0] = 0; 52675d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 52775d3a19aSMatthew G. Knepley orntNew[1] = 0; 52875d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 52975d3a19aSMatthew G. Knepley orntNew[2] = 0; 53075d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 53175d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 53275d3a19aSMatthew G. Knepley #if 1 53375d3a19aSMatthew 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); 53475d3a19aSMatthew G. Knepley for (p = 0; p < 3; ++p) { 53575d3a19aSMatthew 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); 53675d3a19aSMatthew G. Knepley } 53775d3a19aSMatthew G. Knepley #endif 53875d3a19aSMatthew G. Knepley } 53975d3a19aSMatthew G. Knepley /* Split faces have 2 vertices and the same cells as the parent */ 54075d3a19aSMatthew G. Knepley ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 54175d3a19aSMatthew G. Knepley ierr = PetscMalloc((2 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr); 54275d3a19aSMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 54375d3a19aSMatthew G. Knepley const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 54475d3a19aSMatthew G. Knepley 54575d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 54675d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (f - fStart)*2 + r; 54775d3a19aSMatthew G. Knepley const PetscInt *cone, *support; 54875d3a19aSMatthew G. Knepley PetscInt coneNew[2], coneSize, c, supportSize, s; 54975d3a19aSMatthew G. Knepley 55075d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 55175d3a19aSMatthew G. Knepley coneNew[0] = vStartNew + (cone[0] - vStart); 55275d3a19aSMatthew G. Knepley coneNew[1] = vStartNew + (cone[1] - vStart); 55375d3a19aSMatthew G. Knepley coneNew[(r+1)%2] = newv; 55475d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 55575d3a19aSMatthew G. Knepley #if 1 55675d3a19aSMatthew 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); 55775d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 55875d3a19aSMatthew 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); 55975d3a19aSMatthew G. Knepley } 56075d3a19aSMatthew G. Knepley #endif 56175d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 56275d3a19aSMatthew G. Knepley ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 56375d3a19aSMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 56475d3a19aSMatthew G. Knepley ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 56575d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 56675d3a19aSMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 56775d3a19aSMatthew G. Knepley if (cone[c] == f) break; 56875d3a19aSMatthew G. Knepley } 56975d3a19aSMatthew G. Knepley supportRef[s] = cStartNew + (support[s] - cStart)*4 + (c+r)%3; 57075d3a19aSMatthew G. Knepley } 57175d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 57275d3a19aSMatthew G. Knepley #if 1 57375d3a19aSMatthew 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); 57475d3a19aSMatthew G. Knepley for (p = 0; p < supportSize; ++p) { 57575d3a19aSMatthew 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); 57675d3a19aSMatthew G. Knepley } 57775d3a19aSMatthew G. Knepley #endif 57875d3a19aSMatthew G. Knepley } 57975d3a19aSMatthew G. Knepley } 58075d3a19aSMatthew G. Knepley /* Interior faces have 2 vertices and 2 cells */ 58175d3a19aSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 58275d3a19aSMatthew G. Knepley const PetscInt *cone; 58375d3a19aSMatthew G. Knepley 58475d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 58575d3a19aSMatthew G. Knepley for (r = 0; r < 3; ++r) { 58675d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 58775d3a19aSMatthew G. Knepley PetscInt coneNew[2]; 58875d3a19aSMatthew G. Knepley PetscInt supportNew[2]; 58975d3a19aSMatthew G. Knepley 59075d3a19aSMatthew G. Knepley coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 59175d3a19aSMatthew G. Knepley coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 59275d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 59375d3a19aSMatthew G. Knepley #if 1 59475d3a19aSMatthew 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); 59575d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 59675d3a19aSMatthew 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); 59775d3a19aSMatthew G. Knepley } 59875d3a19aSMatthew G. Knepley #endif 59975d3a19aSMatthew G. Knepley supportNew[0] = (c - cStart)*4 + (r+1)%3; 60075d3a19aSMatthew G. Knepley supportNew[1] = (c - cStart)*4 + 3; 60175d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 60275d3a19aSMatthew G. Knepley #if 1 60375d3a19aSMatthew 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); 60475d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 60575d3a19aSMatthew 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); 60675d3a19aSMatthew G. Knepley } 60775d3a19aSMatthew G. Knepley #endif 60875d3a19aSMatthew G. Knepley } 60975d3a19aSMatthew G. Knepley } 61075d3a19aSMatthew G. Knepley /* Old vertices have identical supports */ 61175d3a19aSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 61275d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (v - vStart); 61375d3a19aSMatthew G. Knepley const PetscInt *support, *cone; 61475d3a19aSMatthew G. Knepley PetscInt size, s; 61575d3a19aSMatthew G. Knepley 61675d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 61775d3a19aSMatthew G. Knepley ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 61875d3a19aSMatthew G. Knepley for (s = 0; s < size; ++s) { 61975d3a19aSMatthew G. Knepley PetscInt r = 0; 62075d3a19aSMatthew G. Knepley 62175d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 62275d3a19aSMatthew G. Knepley if (cone[1] == v) r = 1; 62375d3a19aSMatthew G. Knepley supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 62475d3a19aSMatthew G. Knepley } 62575d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 62675d3a19aSMatthew G. Knepley #if 1 62775d3a19aSMatthew 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); 62875d3a19aSMatthew G. Knepley for (p = 0; p < size; ++p) { 62975d3a19aSMatthew 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); 63075d3a19aSMatthew G. Knepley } 63175d3a19aSMatthew G. Knepley #endif 63275d3a19aSMatthew G. Knepley } 63375d3a19aSMatthew G. Knepley /* Face vertices have 2 + cells*2 supports */ 63475d3a19aSMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 63575d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 63675d3a19aSMatthew G. Knepley const PetscInt *cone, *support; 63775d3a19aSMatthew G. Knepley PetscInt size, s; 63875d3a19aSMatthew G. Knepley 63975d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 64075d3a19aSMatthew G. Knepley ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 64175d3a19aSMatthew G. Knepley supportRef[0] = fStartNew + (f - fStart)*2 + 0; 64275d3a19aSMatthew G. Knepley supportRef[1] = fStartNew + (f - fStart)*2 + 1; 64375d3a19aSMatthew G. Knepley for (s = 0; s < size; ++s) { 64475d3a19aSMatthew G. Knepley PetscInt r = 0; 64575d3a19aSMatthew G. Knepley 64675d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 64775d3a19aSMatthew G. Knepley if (cone[1] == f) r = 1; 64875d3a19aSMatthew G. Knepley else if (cone[2] == f) r = 2; 64975d3a19aSMatthew G. Knepley supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 65075d3a19aSMatthew G. Knepley supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 65175d3a19aSMatthew G. Knepley } 65275d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 65375d3a19aSMatthew G. Knepley #if 1 65475d3a19aSMatthew 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); 65575d3a19aSMatthew G. Knepley for (p = 0; p < 2+size*2; ++p) { 65675d3a19aSMatthew 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); 65775d3a19aSMatthew G. Knepley } 65875d3a19aSMatthew G. Knepley #endif 65975d3a19aSMatthew G. Knepley } 66075d3a19aSMatthew G. Knepley ierr = PetscFree(supportRef);CHKERRQ(ierr); 66175d3a19aSMatthew G. Knepley break; 66275d3a19aSMatthew G. Knepley case 2: 66375d3a19aSMatthew G. Knepley /* Hex 2D */ 66475d3a19aSMatthew G. Knepley /* 66575d3a19aSMatthew G. Knepley 3---------2---------2 66675d3a19aSMatthew G. Knepley | | | 66775d3a19aSMatthew G. Knepley | D 2 C | 66875d3a19aSMatthew G. Knepley | | | 66975d3a19aSMatthew G. Knepley 3----3----0----1----1 67075d3a19aSMatthew G. Knepley | | | 67175d3a19aSMatthew G. Knepley | A 0 B | 67275d3a19aSMatthew G. Knepley | | | 67375d3a19aSMatthew G. Knepley 0---------0---------1 67475d3a19aSMatthew G. Knepley */ 67575d3a19aSMatthew G. Knepley /* All cells have 4 faces */ 67675d3a19aSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 67775d3a19aSMatthew G. Knepley const PetscInt newp = (c - cStart)*4; 67875d3a19aSMatthew G. Knepley const PetscInt *cone, *ornt; 67975d3a19aSMatthew G. Knepley PetscInt coneNew[4], orntNew[4]; 68075d3a19aSMatthew G. Knepley 68175d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 68275d3a19aSMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 68375d3a19aSMatthew G. Knepley /* A quad */ 68475d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 68575d3a19aSMatthew G. Knepley orntNew[0] = ornt[0]; 68675d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 68775d3a19aSMatthew G. Knepley orntNew[1] = 0; 68875d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 68975d3a19aSMatthew G. Knepley orntNew[2] = -2; 69075d3a19aSMatthew G. Knepley coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 69175d3a19aSMatthew G. Knepley orntNew[3] = ornt[3]; 69275d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 69375d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 69475d3a19aSMatthew G. Knepley #if 1 69575d3a19aSMatthew 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); 69675d3a19aSMatthew G. Knepley for (p = 0; p < 4; ++p) { 69775d3a19aSMatthew 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); 69875d3a19aSMatthew G. Knepley } 69975d3a19aSMatthew G. Knepley #endif 70075d3a19aSMatthew G. Knepley /* B quad */ 70175d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 70275d3a19aSMatthew G. Knepley orntNew[0] = ornt[0]; 70375d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 70475d3a19aSMatthew G. Knepley orntNew[1] = ornt[1]; 70575d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 70675d3a19aSMatthew G. Knepley orntNew[2] = 0; 70775d3a19aSMatthew G. Knepley coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 70875d3a19aSMatthew G. Knepley orntNew[3] = -2; 70975d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 71075d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 71175d3a19aSMatthew G. Knepley #if 1 71275d3a19aSMatthew 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); 71375d3a19aSMatthew G. Knepley for (p = 0; p < 4; ++p) { 71475d3a19aSMatthew 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); 71575d3a19aSMatthew G. Knepley } 71675d3a19aSMatthew G. Knepley #endif 71775d3a19aSMatthew G. Knepley /* C quad */ 71875d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 71975d3a19aSMatthew G. Knepley orntNew[0] = -2; 72075d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 72175d3a19aSMatthew G. Knepley orntNew[1] = ornt[1]; 72275d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 72375d3a19aSMatthew G. Knepley orntNew[2] = ornt[2]; 72475d3a19aSMatthew G. Knepley coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 72575d3a19aSMatthew G. Knepley orntNew[3] = 0; 72675d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 72775d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 72875d3a19aSMatthew G. Knepley #if 1 72975d3a19aSMatthew 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); 73075d3a19aSMatthew G. Knepley for (p = 0; p < 4; ++p) { 73175d3a19aSMatthew 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); 73275d3a19aSMatthew G. Knepley } 73375d3a19aSMatthew G. Knepley #endif 73475d3a19aSMatthew G. Knepley /* D quad */ 73575d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 73675d3a19aSMatthew G. Knepley orntNew[0] = 0; 73775d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 73875d3a19aSMatthew G. Knepley orntNew[1] = -2; 73975d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 74075d3a19aSMatthew G. Knepley orntNew[2] = ornt[2]; 74175d3a19aSMatthew G. Knepley coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 74275d3a19aSMatthew G. Knepley orntNew[3] = ornt[3]; 74375d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 74475d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 74575d3a19aSMatthew G. Knepley #if 1 74675d3a19aSMatthew 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); 74775d3a19aSMatthew G. Knepley for (p = 0; p < 4; ++p) { 74875d3a19aSMatthew 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); 74975d3a19aSMatthew G. Knepley } 75075d3a19aSMatthew G. Knepley #endif 75175d3a19aSMatthew G. Knepley } 75275d3a19aSMatthew G. Knepley /* Split faces have 2 vertices and the same cells as the parent */ 75375d3a19aSMatthew G. Knepley ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 75475d3a19aSMatthew G. Knepley ierr = PetscMalloc((2 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr); 75575d3a19aSMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 75675d3a19aSMatthew G. Knepley const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 75775d3a19aSMatthew G. Knepley 75875d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 75975d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (f - fStart)*2 + r; 76075d3a19aSMatthew G. Knepley const PetscInt *cone, *support; 76175d3a19aSMatthew G. Knepley PetscInt coneNew[2], coneSize, c, supportSize, s; 76275d3a19aSMatthew G. Knepley 76375d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 76475d3a19aSMatthew G. Knepley coneNew[0] = vStartNew + (cone[0] - vStart); 76575d3a19aSMatthew G. Knepley coneNew[1] = vStartNew + (cone[1] - vStart); 76675d3a19aSMatthew G. Knepley coneNew[(r+1)%2] = newv; 76775d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 76875d3a19aSMatthew G. Knepley #if 1 76975d3a19aSMatthew 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); 77075d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 77175d3a19aSMatthew 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); 77275d3a19aSMatthew G. Knepley } 77375d3a19aSMatthew G. Knepley #endif 77475d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 77575d3a19aSMatthew G. Knepley ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 77675d3a19aSMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 77775d3a19aSMatthew G. Knepley ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 77875d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 77975d3a19aSMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 78075d3a19aSMatthew G. Knepley if (cone[c] == f) break; 78175d3a19aSMatthew G. Knepley } 78275d3a19aSMatthew G. Knepley supportRef[s] = cStartNew + (support[s] - cStart)*4 + (c+r)%4; 78375d3a19aSMatthew G. Knepley } 78475d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 78575d3a19aSMatthew G. Knepley #if 1 78675d3a19aSMatthew 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); 78775d3a19aSMatthew G. Knepley for (p = 0; p < supportSize; ++p) { 78875d3a19aSMatthew 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); 78975d3a19aSMatthew G. Knepley } 79075d3a19aSMatthew G. Knepley #endif 79175d3a19aSMatthew G. Knepley } 79275d3a19aSMatthew G. Knepley } 79375d3a19aSMatthew G. Knepley /* Interior faces have 2 vertices and 2 cells */ 79475d3a19aSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 79575d3a19aSMatthew G. Knepley const PetscInt *cone; 79675d3a19aSMatthew G. Knepley PetscInt coneNew[2], supportNew[2]; 79775d3a19aSMatthew G. Knepley 79875d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 79975d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r) { 80075d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 80175d3a19aSMatthew G. Knepley 80275d3a19aSMatthew G. Knepley coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 80375d3a19aSMatthew G. Knepley coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 80475d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 80575d3a19aSMatthew G. Knepley #if 1 80675d3a19aSMatthew 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); 80775d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 80875d3a19aSMatthew 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); 80975d3a19aSMatthew G. Knepley } 81075d3a19aSMatthew G. Knepley #endif 81175d3a19aSMatthew G. Knepley supportNew[0] = (c - cStart)*4 + r; 81275d3a19aSMatthew G. Knepley supportNew[1] = (c - cStart)*4 + (r+1)%4; 81375d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 81475d3a19aSMatthew G. Knepley #if 1 81575d3a19aSMatthew 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); 81675d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 81775d3a19aSMatthew 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); 81875d3a19aSMatthew G. Knepley } 81975d3a19aSMatthew G. Knepley #endif 82075d3a19aSMatthew G. Knepley } 82175d3a19aSMatthew G. Knepley } 82275d3a19aSMatthew G. Knepley /* Old vertices have identical supports */ 82375d3a19aSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 82475d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (v - vStart); 82575d3a19aSMatthew G. Knepley const PetscInt *support, *cone; 82675d3a19aSMatthew G. Knepley PetscInt size, s; 82775d3a19aSMatthew G. Knepley 82875d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 82975d3a19aSMatthew G. Knepley ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 83075d3a19aSMatthew G. Knepley for (s = 0; s < size; ++s) { 83175d3a19aSMatthew G. Knepley PetscInt r = 0; 83275d3a19aSMatthew G. Knepley 83375d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 83475d3a19aSMatthew G. Knepley if (cone[1] == v) r = 1; 83575d3a19aSMatthew G. Knepley supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 83675d3a19aSMatthew G. Knepley } 83775d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 83875d3a19aSMatthew G. Knepley #if 1 83975d3a19aSMatthew 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); 84075d3a19aSMatthew G. Knepley for (p = 0; p < size; ++p) { 84175d3a19aSMatthew 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); 84275d3a19aSMatthew G. Knepley } 84375d3a19aSMatthew G. Knepley #endif 84475d3a19aSMatthew G. Knepley } 84575d3a19aSMatthew G. Knepley /* Face vertices have 2 + cells supports */ 84675d3a19aSMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 84775d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 84875d3a19aSMatthew G. Knepley const PetscInt *cone, *support; 84975d3a19aSMatthew G. Knepley PetscInt size, s; 85075d3a19aSMatthew G. Knepley 85175d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 85275d3a19aSMatthew G. Knepley ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 85375d3a19aSMatthew G. Knepley supportRef[0] = fStartNew + (f - fStart)*2 + 0; 85475d3a19aSMatthew G. Knepley supportRef[1] = fStartNew + (f - fStart)*2 + 1; 85575d3a19aSMatthew G. Knepley for (s = 0; s < size; ++s) { 85675d3a19aSMatthew G. Knepley PetscInt r = 0; 85775d3a19aSMatthew G. Knepley 85875d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 85975d3a19aSMatthew G. Knepley if (cone[1] == f) r = 1; 86075d3a19aSMatthew G. Knepley else if (cone[2] == f) r = 2; 86175d3a19aSMatthew G. Knepley else if (cone[3] == f) r = 3; 86275d3a19aSMatthew G. Knepley supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r; 86375d3a19aSMatthew G. Knepley } 86475d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 86575d3a19aSMatthew G. Knepley #if 1 86675d3a19aSMatthew 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); 86775d3a19aSMatthew G. Knepley for (p = 0; p < 2+size; ++p) { 86875d3a19aSMatthew 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); 86975d3a19aSMatthew G. Knepley } 87075d3a19aSMatthew G. Knepley #endif 87175d3a19aSMatthew G. Knepley } 87275d3a19aSMatthew G. Knepley /* Cell vertices have 4 supports */ 87375d3a19aSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 87475d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 87575d3a19aSMatthew G. Knepley PetscInt supportNew[4]; 87675d3a19aSMatthew G. Knepley 87775d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r) { 87875d3a19aSMatthew G. Knepley supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 87975d3a19aSMatthew G. Knepley } 88075d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 88175d3a19aSMatthew G. Knepley } 88275d3a19aSMatthew G. Knepley break; 88375d3a19aSMatthew G. Knepley case 3: 88475d3a19aSMatthew G. Knepley if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 88575d3a19aSMatthew G. Knepley cMax = PetscMin(cEnd, cMax); 88675d3a19aSMatthew G. Knepley if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 88775d3a19aSMatthew G. Knepley fMax = PetscMin(fEnd, fMax); 88875d3a19aSMatthew G. Knepley /* Interior cells have 3 faces */ 88975d3a19aSMatthew G. Knepley for (c = cStart; c < cMax; ++c) { 89075d3a19aSMatthew G. Knepley const PetscInt newp = cStartNew + (c - cStart)*4; 89175d3a19aSMatthew G. Knepley const PetscInt *cone, *ornt; 89275d3a19aSMatthew G. Knepley PetscInt coneNew[3], orntNew[3]; 89375d3a19aSMatthew G. Knepley 89475d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 89575d3a19aSMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 89675d3a19aSMatthew G. Knepley /* A triangle */ 89775d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 89875d3a19aSMatthew G. Knepley orntNew[0] = ornt[0]; 89975d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 90075d3a19aSMatthew G. Knepley orntNew[1] = -2; 90175d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 90275d3a19aSMatthew G. Knepley orntNew[2] = ornt[2]; 90375d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 90475d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 90575d3a19aSMatthew G. Knepley #if 1 90675d3a19aSMatthew 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); 90775d3a19aSMatthew G. Knepley for (p = 0; p < 3; ++p) { 90875d3a19aSMatthew 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); 90975d3a19aSMatthew G. Knepley } 91075d3a19aSMatthew G. Knepley #endif 91175d3a19aSMatthew G. Knepley /* B triangle */ 91275d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 91375d3a19aSMatthew G. Knepley orntNew[0] = ornt[0]; 91475d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 91575d3a19aSMatthew G. Knepley orntNew[1] = ornt[1]; 91675d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 91775d3a19aSMatthew G. Knepley orntNew[2] = -2; 91875d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 91975d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 92075d3a19aSMatthew G. Knepley #if 1 92175d3a19aSMatthew 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); 92275d3a19aSMatthew G. Knepley for (p = 0; p < 3; ++p) { 92375d3a19aSMatthew 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); 92475d3a19aSMatthew G. Knepley } 92575d3a19aSMatthew G. Knepley #endif 92675d3a19aSMatthew G. Knepley /* C triangle */ 92775d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 92875d3a19aSMatthew G. Knepley orntNew[0] = -2; 92975d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 93075d3a19aSMatthew G. Knepley orntNew[1] = ornt[1]; 93175d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 93275d3a19aSMatthew G. Knepley orntNew[2] = ornt[2]; 93375d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 93475d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 93575d3a19aSMatthew G. Knepley #if 1 93675d3a19aSMatthew 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); 93775d3a19aSMatthew G. Knepley for (p = 0; p < 3; ++p) { 93875d3a19aSMatthew 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); 93975d3a19aSMatthew G. Knepley } 94075d3a19aSMatthew G. Knepley #endif 94175d3a19aSMatthew G. Knepley /* D triangle */ 94275d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 94375d3a19aSMatthew G. Knepley orntNew[0] = 0; 94475d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 94575d3a19aSMatthew G. Knepley orntNew[1] = 0; 94675d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 94775d3a19aSMatthew G. Knepley orntNew[2] = 0; 94875d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 94975d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 95075d3a19aSMatthew G. Knepley #if 1 95175d3a19aSMatthew 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); 95275d3a19aSMatthew G. Knepley for (p = 0; p < 3; ++p) { 95375d3a19aSMatthew 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); 95475d3a19aSMatthew G. Knepley } 95575d3a19aSMatthew G. Knepley #endif 95675d3a19aSMatthew G. Knepley } 95775d3a19aSMatthew G. Knepley /* 95875d3a19aSMatthew G. Knepley 2----3----3 95975d3a19aSMatthew G. Knepley | | 96075d3a19aSMatthew G. Knepley | B | 96175d3a19aSMatthew G. Knepley | | 96275d3a19aSMatthew G. Knepley 0----4--- 1 96375d3a19aSMatthew G. Knepley | | 96475d3a19aSMatthew G. Knepley | A | 96575d3a19aSMatthew G. Knepley | | 96675d3a19aSMatthew G. Knepley 0----2----1 96775d3a19aSMatthew G. Knepley */ 96875d3a19aSMatthew G. Knepley /* Hybrid cells have 4 faces */ 96975d3a19aSMatthew G. Knepley for (c = cMax; c < cEnd; ++c) { 97075d3a19aSMatthew G. Knepley const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 97175d3a19aSMatthew G. Knepley const PetscInt *cone, *ornt; 97275d3a19aSMatthew G. Knepley PetscInt coneNew[4], orntNew[4]; 97375d3a19aSMatthew G. Knepley 97475d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 97575d3a19aSMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 97675d3a19aSMatthew G. Knepley /* A quad */ 97775d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 97875d3a19aSMatthew G. Knepley orntNew[0] = ornt[0]; 97975d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 98075d3a19aSMatthew G. Knepley orntNew[1] = ornt[1]; 98175d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2] - fMax); 98275d3a19aSMatthew G. Knepley orntNew[2] = 0; 98375d3a19aSMatthew G. Knepley coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 98475d3a19aSMatthew G. Knepley orntNew[3] = 0; 98575d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 98675d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 98775d3a19aSMatthew G. Knepley #if 1 98875d3a19aSMatthew 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); 98975d3a19aSMatthew G. Knepley for (p = 0; p < 4; ++p) { 99075d3a19aSMatthew 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); 99175d3a19aSMatthew G. Knepley } 99275d3a19aSMatthew G. Knepley #endif 99375d3a19aSMatthew G. Knepley /* B quad */ 99475d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 99575d3a19aSMatthew G. Knepley orntNew[0] = ornt[0]; 99675d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 99775d3a19aSMatthew G. Knepley orntNew[1] = ornt[1]; 99875d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 99975d3a19aSMatthew G. Knepley orntNew[2] = 0; 100075d3a19aSMatthew G. Knepley coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3] - fMax); 100175d3a19aSMatthew G. Knepley orntNew[3] = 0; 100275d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 100375d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 100475d3a19aSMatthew G. Knepley #if 1 100575d3a19aSMatthew 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); 100675d3a19aSMatthew G. Knepley for (p = 0; p < 4; ++p) { 100775d3a19aSMatthew 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); 100875d3a19aSMatthew G. Knepley } 100975d3a19aSMatthew G. Knepley #endif 101075d3a19aSMatthew G. Knepley } 101175d3a19aSMatthew G. Knepley /* Interior split faces have 2 vertices and the same cells as the parent */ 101275d3a19aSMatthew G. Knepley ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 101375d3a19aSMatthew G. Knepley ierr = PetscMalloc((2 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr); 101475d3a19aSMatthew G. Knepley for (f = fStart; f < fMax; ++f) { 101575d3a19aSMatthew G. Knepley const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 101675d3a19aSMatthew G. Knepley 101775d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 101875d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (f - fStart)*2 + r; 101975d3a19aSMatthew G. Knepley const PetscInt *cone, *support; 102075d3a19aSMatthew G. Knepley PetscInt coneNew[2], coneSize, c, supportSize, s; 102175d3a19aSMatthew G. Knepley 102275d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 102375d3a19aSMatthew G. Knepley coneNew[0] = vStartNew + (cone[0] - vStart); 102475d3a19aSMatthew G. Knepley coneNew[1] = vStartNew + (cone[1] - vStart); 102575d3a19aSMatthew G. Knepley coneNew[(r+1)%2] = newv; 102675d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 102775d3a19aSMatthew G. Knepley #if 1 102875d3a19aSMatthew 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); 102975d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 103075d3a19aSMatthew 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); 103175d3a19aSMatthew G. Knepley } 103275d3a19aSMatthew G. Knepley #endif 103375d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 103475d3a19aSMatthew G. Knepley ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 103575d3a19aSMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 103675d3a19aSMatthew G. Knepley if (support[s] >= cMax) { 103775d3a19aSMatthew G. Knepley supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 103875d3a19aSMatthew G. Knepley } else { 103975d3a19aSMatthew G. Knepley ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 104075d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 104175d3a19aSMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 104275d3a19aSMatthew G. Knepley if (cone[c] == f) break; 104375d3a19aSMatthew G. Knepley } 104475d3a19aSMatthew G. Knepley supportRef[s] = cStartNew + (support[s] - cStart)*4 + (c+r)%3; 104575d3a19aSMatthew G. Knepley } 104675d3a19aSMatthew G. Knepley } 104775d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 104875d3a19aSMatthew G. Knepley #if 1 104975d3a19aSMatthew 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); 105075d3a19aSMatthew G. Knepley for (p = 0; p < supportSize; ++p) { 105175d3a19aSMatthew 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); 105275d3a19aSMatthew G. Knepley } 105375d3a19aSMatthew G. Knepley #endif 105475d3a19aSMatthew G. Knepley } 105575d3a19aSMatthew G. Knepley } 105675d3a19aSMatthew G. Knepley /* Interior cell faces have 2 vertices and 2 cells */ 105775d3a19aSMatthew G. Knepley for (c = cStart; c < cMax; ++c) { 105875d3a19aSMatthew G. Knepley const PetscInt *cone; 105975d3a19aSMatthew G. Knepley 106075d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 106175d3a19aSMatthew G. Knepley for (r = 0; r < 3; ++r) { 106275d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 106375d3a19aSMatthew G. Knepley PetscInt coneNew[2]; 106475d3a19aSMatthew G. Knepley PetscInt supportNew[2]; 106575d3a19aSMatthew G. Knepley 106675d3a19aSMatthew G. Knepley coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 106775d3a19aSMatthew G. Knepley coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 106875d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 106975d3a19aSMatthew G. Knepley #if 1 107075d3a19aSMatthew 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); 107175d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 107275d3a19aSMatthew 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); 107375d3a19aSMatthew G. Knepley } 107475d3a19aSMatthew G. Knepley #endif 107575d3a19aSMatthew G. Knepley supportNew[0] = (c - cStart)*4 + (r+1)%3; 107675d3a19aSMatthew G. Knepley supportNew[1] = (c - cStart)*4 + 3; 107775d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 107875d3a19aSMatthew G. Knepley #if 1 107975d3a19aSMatthew 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); 108075d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 108175d3a19aSMatthew 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); 108275d3a19aSMatthew G. Knepley } 108375d3a19aSMatthew G. Knepley #endif 108475d3a19aSMatthew G. Knepley } 108575d3a19aSMatthew G. Knepley } 108675d3a19aSMatthew G. Knepley /* Interior hybrid faces have 2 vertices and the same cells */ 108775d3a19aSMatthew G. Knepley for (f = fMax; f < fEnd; ++f) { 108875d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 108975d3a19aSMatthew G. Knepley const PetscInt *cone; 109075d3a19aSMatthew G. Knepley const PetscInt *support; 109175d3a19aSMatthew G. Knepley PetscInt coneNew[2]; 109275d3a19aSMatthew G. Knepley PetscInt supportNew[2]; 109375d3a19aSMatthew G. Knepley PetscInt size, s, r; 109475d3a19aSMatthew G. Knepley 109575d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 109675d3a19aSMatthew G. Knepley coneNew[0] = vStartNew + (cone[0] - vStart); 109775d3a19aSMatthew G. Knepley coneNew[1] = vStartNew + (cone[1] - vStart); 109875d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 109975d3a19aSMatthew G. Knepley #if 1 110075d3a19aSMatthew 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); 110175d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 110275d3a19aSMatthew 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); 110375d3a19aSMatthew G. Knepley } 110475d3a19aSMatthew G. Knepley #endif 110575d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 110675d3a19aSMatthew G. Knepley ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 110775d3a19aSMatthew G. Knepley for (s = 0; s < size; ++s) { 110875d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 110975d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 111075d3a19aSMatthew G. Knepley if (cone[r+2] == f) break; 111175d3a19aSMatthew G. Knepley } 111275d3a19aSMatthew G. Knepley supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 111375d3a19aSMatthew G. Knepley } 111475d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 111575d3a19aSMatthew G. Knepley #if 1 111675d3a19aSMatthew 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); 111775d3a19aSMatthew G. Knepley for (p = 0; p < size; ++p) { 111875d3a19aSMatthew 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); 111975d3a19aSMatthew G. Knepley } 112075d3a19aSMatthew G. Knepley #endif 112175d3a19aSMatthew G. Knepley } 112275d3a19aSMatthew G. Knepley /* Cell hybrid faces have 2 vertices and 2 cells */ 112375d3a19aSMatthew G. Knepley for (c = cMax; c < cEnd; ++c) { 112475d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 112575d3a19aSMatthew G. Knepley const PetscInt *cone; 112675d3a19aSMatthew G. Knepley PetscInt coneNew[2]; 112775d3a19aSMatthew G. Knepley PetscInt supportNew[2]; 112875d3a19aSMatthew G. Knepley 112975d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 113075d3a19aSMatthew G. Knepley coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 113175d3a19aSMatthew G. Knepley coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 113275d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 113375d3a19aSMatthew G. Knepley #if 1 113475d3a19aSMatthew 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); 113575d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 113675d3a19aSMatthew 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); 113775d3a19aSMatthew G. Knepley } 113875d3a19aSMatthew G. Knepley #endif 113975d3a19aSMatthew G. Knepley supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 114075d3a19aSMatthew G. Knepley supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 114175d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 114275d3a19aSMatthew G. Knepley #if 1 114375d3a19aSMatthew 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); 114475d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 114575d3a19aSMatthew 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); 114675d3a19aSMatthew G. Knepley } 114775d3a19aSMatthew G. Knepley #endif 114875d3a19aSMatthew G. Knepley } 114975d3a19aSMatthew G. Knepley /* Old vertices have identical supports */ 115075d3a19aSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 115175d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (v - vStart); 115275d3a19aSMatthew G. Knepley const PetscInt *support, *cone; 115375d3a19aSMatthew G. Knepley PetscInt size, s; 115475d3a19aSMatthew G. Knepley 115575d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 115675d3a19aSMatthew G. Knepley ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 115775d3a19aSMatthew G. Knepley for (s = 0; s < size; ++s) { 115875d3a19aSMatthew G. Knepley if (support[s] >= fMax) { 115975d3a19aSMatthew G. Knepley supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax); 116075d3a19aSMatthew G. Knepley } else { 116175d3a19aSMatthew G. Knepley PetscInt r = 0; 116275d3a19aSMatthew G. Knepley 116375d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 116475d3a19aSMatthew G. Knepley if (cone[1] == v) r = 1; 116575d3a19aSMatthew G. Knepley supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 116675d3a19aSMatthew G. Knepley } 116775d3a19aSMatthew G. Knepley } 116875d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 116975d3a19aSMatthew G. Knepley #if 1 117075d3a19aSMatthew 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); 117175d3a19aSMatthew G. Knepley for (p = 0; p < size; ++p) { 117275d3a19aSMatthew 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); 117375d3a19aSMatthew G. Knepley } 117475d3a19aSMatthew G. Knepley #endif 117575d3a19aSMatthew G. Knepley } 117675d3a19aSMatthew G. Knepley /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 117775d3a19aSMatthew G. Knepley for (f = fStart; f < fMax; ++f) { 117875d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 117975d3a19aSMatthew G. Knepley const PetscInt *cone, *support; 118075d3a19aSMatthew G. Knepley PetscInt size, newSize = 2, s; 118175d3a19aSMatthew G. Knepley 118275d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 118375d3a19aSMatthew G. Knepley ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 118475d3a19aSMatthew G. Knepley supportRef[0] = fStartNew + (f - fStart)*2 + 0; 118575d3a19aSMatthew G. Knepley supportRef[1] = fStartNew + (f - fStart)*2 + 1; 118675d3a19aSMatthew G. Knepley for (s = 0; s < size; ++s) { 118775d3a19aSMatthew G. Knepley PetscInt r = 0; 118875d3a19aSMatthew G. Knepley 118975d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 119075d3a19aSMatthew G. Knepley if (support[s] >= cMax) { 119175d3a19aSMatthew G. Knepley supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax); 119275d3a19aSMatthew G. Knepley 119375d3a19aSMatthew G. Knepley newSize += 1; 119475d3a19aSMatthew G. Knepley } else { 119575d3a19aSMatthew G. Knepley if (cone[1] == f) r = 1; 119675d3a19aSMatthew G. Knepley else if (cone[2] == f) r = 2; 119775d3a19aSMatthew G. Knepley supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 119875d3a19aSMatthew G. Knepley supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r; 119975d3a19aSMatthew G. Knepley 120075d3a19aSMatthew G. Knepley newSize += 2; 120175d3a19aSMatthew G. Knepley } 120275d3a19aSMatthew G. Knepley } 120375d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 120475d3a19aSMatthew G. Knepley #if 1 120575d3a19aSMatthew 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); 120675d3a19aSMatthew G. Knepley for (p = 0; p < newSize; ++p) { 120775d3a19aSMatthew 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); 120875d3a19aSMatthew G. Knepley } 120975d3a19aSMatthew G. Knepley #endif 121075d3a19aSMatthew G. Knepley } 121175d3a19aSMatthew G. Knepley ierr = PetscFree(supportRef);CHKERRQ(ierr); 121275d3a19aSMatthew G. Knepley break; 1213*b5da9499SMatthew G. Knepley case 5: 1214*b5da9499SMatthew G. Knepley /* Simplicial 3D */ 1215*b5da9499SMatthew G. Knepley /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 1216*b5da9499SMatthew G. Knepley ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 1217*b5da9499SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1218*b5da9499SMatthew G. Knepley const PetscInt newp = cStartNew + (c - cStart)*8; 1219*b5da9499SMatthew G. Knepley const PetscInt *cone, *ornt; 1220*b5da9499SMatthew G. Knepley PetscInt coneNew[4], orntNew[4]; 1221*b5da9499SMatthew G. Knepley 1222*b5da9499SMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1223*b5da9499SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1224*b5da9499SMatthew G. Knepley /* A tetrahedron: {0, a, c, d} */ 1225*b5da9499SMatthew G. Knepley coneNew[0] = fStartNew + (cone[0] - fStart)*4 + (ornt[0] < 0 ? (-(ornt[0]+1)+1)%3 : ornt[0]); /* A */ 1226*b5da9499SMatthew G. Knepley orntNew[0] = ornt[0]; 1227*b5da9499SMatthew G. Knepley coneNew[1] = fStartNew + (cone[1] - fStart)*4 + (ornt[1] < 0 ? (-(ornt[1]+1)+1)%3 : ornt[1]); /* A */ 1228*b5da9499SMatthew G. Knepley orntNew[1] = ornt[1]; 1229*b5da9499SMatthew G. Knepley coneNew[2] = fStartNew + (cone[2] - fStart)*4 + (ornt[2] < 0 ? (-(ornt[2]+1)+1)%3 : ornt[2]); /* A */ 1230*b5da9499SMatthew G. Knepley orntNew[2] = ornt[2]; 1231*b5da9499SMatthew G. Knepley coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 1232*b5da9499SMatthew G. Knepley orntNew[3] = 0; 1233*b5da9499SMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1234*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1235*b5da9499SMatthew G. Knepley #if 1 1236*b5da9499SMatthew 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); 1237*b5da9499SMatthew G. Knepley for (p = 0; p < 4; ++p) { 1238*b5da9499SMatthew 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); 1239*b5da9499SMatthew G. Knepley } 1240*b5da9499SMatthew G. Knepley #endif 1241*b5da9499SMatthew G. Knepley /* B tetrahedron: {a, 1, b, e} */ 1242*b5da9499SMatthew G. Knepley coneNew[0] = fStartNew + (cone[0] - fStart)*4 + (ornt[0] < 0 ? (-(ornt[0]+1)+0)%3 : (ornt[0]+1)%3); /* B */ 1243*b5da9499SMatthew G. Knepley orntNew[0] = ornt[0]; 1244*b5da9499SMatthew G. Knepley coneNew[1] = fStartNew + (cone[1] - fStart)*4 + (ornt[1] < 0 ? (-(ornt[1]+1)+2)%3 : (ornt[1]+2)%3); /* C */ 1245*b5da9499SMatthew G. Knepley orntNew[1] = ornt[1]; 1246*b5da9499SMatthew G. Knepley coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 1247*b5da9499SMatthew G. Knepley orntNew[2] = 0; 1248*b5da9499SMatthew G. Knepley coneNew[3] = fStartNew + (cone[3] - fStart)*4 + (ornt[3] < 0 ? (-(ornt[3]+1)+0)%3 : (ornt[3]+1)%3); /* B */ 1249*b5da9499SMatthew G. Knepley orntNew[3] = ornt[3]; 1250*b5da9499SMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1251*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1252*b5da9499SMatthew G. Knepley #if 1 1253*b5da9499SMatthew 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); 1254*b5da9499SMatthew G. Knepley for (p = 0; p < 4; ++p) { 1255*b5da9499SMatthew 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); 1256*b5da9499SMatthew G. Knepley } 1257*b5da9499SMatthew G. Knepley #endif 1258*b5da9499SMatthew G. Knepley /* C tetrahedron: {c, b, 2, f} */ 1259*b5da9499SMatthew G. Knepley coneNew[0] = fStartNew + (cone[0] - fStart)*4 + (ornt[0] < 0 ? (-(ornt[0]+1)+2)%3 : (ornt[0]+2)%3); /* C */ 1260*b5da9499SMatthew G. Knepley orntNew[0] = ornt[0]; 1261*b5da9499SMatthew G. Knepley coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 1262*b5da9499SMatthew G. Knepley orntNew[1] = 0; 1263*b5da9499SMatthew G. Knepley coneNew[2] = fStartNew + (cone[2] - fStart)*4 + (ornt[2] < 0 ? (-(ornt[2]+1)+0)%3 : (ornt[2]+1)%3); /* B */ 1264*b5da9499SMatthew G. Knepley orntNew[2] = ornt[2]; 1265*b5da9499SMatthew G. Knepley coneNew[3] = fStartNew + (cone[3] - fStart)*4 + (ornt[3] < 0 ? (-(ornt[3]+1)+1)%3 : (ornt[3]+0)%3); /* A */ 1266*b5da9499SMatthew G. Knepley orntNew[3] = ornt[3]; 1267*b5da9499SMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1268*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1269*b5da9499SMatthew G. Knepley #if 1 1270*b5da9499SMatthew 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); 1271*b5da9499SMatthew G. Knepley for (p = 0; p < 4; ++p) { 1272*b5da9499SMatthew 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); 1273*b5da9499SMatthew G. Knepley } 1274*b5da9499SMatthew G. Knepley #endif 1275*b5da9499SMatthew G. Knepley /* D tetrahedron: {d, e, f, 3} */ 1276*b5da9499SMatthew G. Knepley coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 1277*b5da9499SMatthew G. Knepley orntNew[0] = 0; 1278*b5da9499SMatthew G. Knepley coneNew[1] = fStartNew + (cone[1] - fStart)*4 + (ornt[1] < 0 ? (-(ornt[1]+1)+0)%3 : (ornt[1]+1)%3); /* B */ 1279*b5da9499SMatthew G. Knepley orntNew[1] = ornt[1]; 1280*b5da9499SMatthew G. Knepley coneNew[2] = fStartNew + (cone[2] - fStart)*4 + (ornt[2] < 0 ? (-(ornt[2]+1)+2)%3 : (ornt[2]+2)%3); /* C */ 1281*b5da9499SMatthew G. Knepley orntNew[2] = ornt[2]; 1282*b5da9499SMatthew G. Knepley coneNew[3] = fStartNew + (cone[3] - fStart)*4 + (ornt[3] < 0 ? (-(ornt[3]+1)+2)%3 : (ornt[3]+2)%3); /* C */ 1283*b5da9499SMatthew G. Knepley orntNew[3] = ornt[3]; 1284*b5da9499SMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1285*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1286*b5da9499SMatthew G. Knepley #if 1 1287*b5da9499SMatthew 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); 1288*b5da9499SMatthew G. Knepley for (p = 0; p < 4; ++p) { 1289*b5da9499SMatthew 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); 1290*b5da9499SMatthew G. Knepley } 1291*b5da9499SMatthew G. Knepley #endif 1292*b5da9499SMatthew G. Knepley /* A' tetrahedron: {d, a, c, f} */ 1293*b5da9499SMatthew G. Knepley coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 1294*b5da9499SMatthew G. Knepley orntNew[0] = -3; 1295*b5da9499SMatthew G. Knepley coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 1296*b5da9499SMatthew G. Knepley orntNew[1] = 0; 1297*b5da9499SMatthew G. Knepley coneNew[2] = fStartNew + (cone[2] - fStart)*4 + 3; 1298*b5da9499SMatthew G. Knepley orntNew[2] = ornt[2] < 0 ? -((-(ornt[2]+1)+2)%3+1) : (ornt[2]+2)%3; 1299*b5da9499SMatthew G. Knepley coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 1300*b5da9499SMatthew G. Knepley orntNew[3] = 0; 1301*b5da9499SMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 1302*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 1303*b5da9499SMatthew G. Knepley #if 1 1304*b5da9499SMatthew G. Knepley if ((newp+4 < cStartNew) || (newp+4 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+4, cStartNew, cEndNew); 1305*b5da9499SMatthew G. Knepley for (p = 0; p < 4; ++p) { 1306*b5da9499SMatthew 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); 1307*b5da9499SMatthew G. Knepley } 1308*b5da9499SMatthew G. Knepley #endif 1309*b5da9499SMatthew G. Knepley /* B' tetrahedron: {e, b, a, f} */ 1310*b5da9499SMatthew G. Knepley coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 1311*b5da9499SMatthew G. Knepley orntNew[0] = -3; 1312*b5da9499SMatthew G. Knepley coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3; 1313*b5da9499SMatthew G. Knepley orntNew[1] = ornt[3] < 0 ? -((-(ornt[3]+1)+1)%3+1) : (ornt[3]+1)%3; 1314*b5da9499SMatthew G. Knepley coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 1315*b5da9499SMatthew G. Knepley orntNew[2] = 0; 1316*b5da9499SMatthew G. Knepley coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 1317*b5da9499SMatthew G. Knepley orntNew[3] = 0; 1318*b5da9499SMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 1319*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 1320*b5da9499SMatthew G. Knepley #if 1 1321*b5da9499SMatthew G. Knepley if ((newp+5 < cStartNew) || (newp+5 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+5, cStartNew, cEndNew); 1322*b5da9499SMatthew G. Knepley for (p = 0; p < 4; ++p) { 1323*b5da9499SMatthew 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); 1324*b5da9499SMatthew G. Knepley } 1325*b5da9499SMatthew G. Knepley #endif 1326*b5da9499SMatthew G. Knepley /* C' tetrahedron: {b, f, c, a} */ 1327*b5da9499SMatthew G. Knepley coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 1328*b5da9499SMatthew G. Knepley orntNew[0] = -3; 1329*b5da9499SMatthew G. Knepley coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 1330*b5da9499SMatthew G. Knepley orntNew[1] = -2; 1331*b5da9499SMatthew G. Knepley coneNew[2] = fStartNew + (cone[0] - fStart)*4 + 3; 1332*b5da9499SMatthew G. Knepley orntNew[2] = ornt[0] < 0 ? (-(ornt[0]+1)+1)%3 : -((ornt[0]+1)%3+1); 1333*b5da9499SMatthew G. Knepley coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 1334*b5da9499SMatthew G. Knepley orntNew[3] = -1; 1335*b5da9499SMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 1336*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 1337*b5da9499SMatthew G. Knepley #if 1 1338*b5da9499SMatthew G. Knepley if ((newp+6 < cStartNew) || (newp+6 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+6, cStartNew, cEndNew); 1339*b5da9499SMatthew G. Knepley for (p = 0; p < 4; ++p) { 1340*b5da9499SMatthew 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); 1341*b5da9499SMatthew G. Knepley } 1342*b5da9499SMatthew G. Knepley #endif 1343*b5da9499SMatthew G. Knepley /* D' tetrahedron: {f, e, d, a} */ 1344*b5da9499SMatthew G. Knepley coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 1345*b5da9499SMatthew G. Knepley orntNew[0] = -3; 1346*b5da9499SMatthew G. Knepley coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 1347*b5da9499SMatthew G. Knepley orntNew[1] = -3; 1348*b5da9499SMatthew G. Knepley coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 1349*b5da9499SMatthew G. Knepley orntNew[2] = -2; 1350*b5da9499SMatthew G. Knepley coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3; 1351*b5da9499SMatthew G. Knepley orntNew[3] = ornt[2]; 1352*b5da9499SMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 1353*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 1354*b5da9499SMatthew G. Knepley #if 1 1355*b5da9499SMatthew G. Knepley if ((newp+7 < cStartNew) || (newp+7 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+7, cStartNew, cEndNew); 1356*b5da9499SMatthew G. Knepley for (p = 0; p < 4; ++p) { 1357*b5da9499SMatthew 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); 1358*b5da9499SMatthew G. Knepley } 1359*b5da9499SMatthew G. Knepley #endif 1360*b5da9499SMatthew G. Knepley } 1361*b5da9499SMatthew G. Knepley /* Split faces have 3 edges and the same cells as the parent */ 1362*b5da9499SMatthew G. Knepley ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1363*b5da9499SMatthew G. Knepley ierr = PetscMalloc((2 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr); 1364*b5da9499SMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 1365*b5da9499SMatthew G. Knepley const PetscInt newp = fStartNew + (f - fStart)*4; 1366*b5da9499SMatthew G. Knepley const PetscInt *cone, *ornt, *support; 1367*b5da9499SMatthew G. Knepley PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 1368*b5da9499SMatthew G. Knepley 1369*b5da9499SMatthew G. Knepley ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1370*b5da9499SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 1371*b5da9499SMatthew G. Knepley /* A triangle */ 1372*b5da9499SMatthew G. Knepley coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 1373*b5da9499SMatthew G. Knepley orntNew[0] = ornt[0]; 1374*b5da9499SMatthew G. Knepley coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 1375*b5da9499SMatthew G. Knepley orntNew[1] = -2; 1376*b5da9499SMatthew G. Knepley coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 1377*b5da9499SMatthew G. Knepley orntNew[2] = ornt[2]; 1378*b5da9499SMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1379*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1380*b5da9499SMatthew G. Knepley #if 1 1381*b5da9499SMatthew G. Knepley if ((newp+0 < fStartNew) || (newp+0 >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+0, fStartNew, fEndNew); 1382*b5da9499SMatthew G. Knepley for (p = 0; p < 3; ++p) { 1383*b5da9499SMatthew G. Knepley if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1384*b5da9499SMatthew G. Knepley } 1385*b5da9499SMatthew G. Knepley #endif 1386*b5da9499SMatthew G. Knepley /* B triangle */ 1387*b5da9499SMatthew G. Knepley coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 1388*b5da9499SMatthew G. Knepley orntNew[0] = ornt[0]; 1389*b5da9499SMatthew G. Knepley coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 1390*b5da9499SMatthew G. Knepley orntNew[1] = ornt[1]; 1391*b5da9499SMatthew G. Knepley coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 1392*b5da9499SMatthew G. Knepley orntNew[2] = -2; 1393*b5da9499SMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1394*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1395*b5da9499SMatthew G. Knepley #if 1 1396*b5da9499SMatthew G. Knepley if ((newp+1 < fStartNew) || (newp+1 >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+1, fStartNew, fEndNew); 1397*b5da9499SMatthew G. Knepley for (p = 0; p < 3; ++p) { 1398*b5da9499SMatthew G. Knepley if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1399*b5da9499SMatthew G. Knepley } 1400*b5da9499SMatthew G. Knepley #endif 1401*b5da9499SMatthew G. Knepley /* C triangle */ 1402*b5da9499SMatthew G. Knepley coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 1403*b5da9499SMatthew G. Knepley orntNew[0] = -2; 1404*b5da9499SMatthew G. Knepley coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 1405*b5da9499SMatthew G. Knepley orntNew[1] = ornt[1]; 1406*b5da9499SMatthew G. Knepley coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 1407*b5da9499SMatthew G. Knepley orntNew[2] = ornt[2]; 1408*b5da9499SMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1409*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1410*b5da9499SMatthew G. Knepley #if 1 1411*b5da9499SMatthew G. Knepley if ((newp+2 < fStartNew) || (newp+2 >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+2, fStartNew, fEndNew); 1412*b5da9499SMatthew G. Knepley for (p = 0; p < 3; ++p) { 1413*b5da9499SMatthew G. Knepley if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1414*b5da9499SMatthew G. Knepley } 1415*b5da9499SMatthew G. Knepley #endif 1416*b5da9499SMatthew G. Knepley /* D triangle */ 1417*b5da9499SMatthew G. Knepley coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 1418*b5da9499SMatthew G. Knepley orntNew[0] = 0; 1419*b5da9499SMatthew G. Knepley coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 1420*b5da9499SMatthew G. Knepley orntNew[1] = 0; 1421*b5da9499SMatthew G. Knepley coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 1422*b5da9499SMatthew G. Knepley orntNew[2] = 0; 1423*b5da9499SMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1424*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1425*b5da9499SMatthew G. Knepley #if 1 1426*b5da9499SMatthew G. Knepley if ((newp+3 < fStartNew) || (newp+3 >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+3, fStartNew, fEndNew); 1427*b5da9499SMatthew G. Knepley for (p = 0; p < 3; ++p) { 1428*b5da9499SMatthew G. Knepley if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1429*b5da9499SMatthew G. Knepley } 1430*b5da9499SMatthew G. Knepley #endif 1431*b5da9499SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1432*b5da9499SMatthew G. Knepley ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1433*b5da9499SMatthew G. Knepley for (r = 0; r < 4; ++r) { 1434*b5da9499SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 1435*b5da9499SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1436*b5da9499SMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1437*b5da9499SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1438*b5da9499SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 1439*b5da9499SMatthew G. Knepley if (cone[c] == f) break; 1440*b5da9499SMatthew G. Knepley } 1441*b5da9499SMatthew G. Knepley supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : (ornt[c] < 0 ? faces[c*3+(-(ornt[c]+1)+1+3-r)%3] : faces[c*3+r])); 1442*b5da9499SMatthew G. Knepley } 1443*b5da9499SMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 1444*b5da9499SMatthew G. Knepley #if 1 1445*b5da9499SMatthew 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); 1446*b5da9499SMatthew G. Knepley for (p = 0; p < supportSize; ++p) { 1447*b5da9499SMatthew 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); 1448*b5da9499SMatthew G. Knepley } 1449*b5da9499SMatthew G. Knepley #endif 1450*b5da9499SMatthew G. Knepley } 1451*b5da9499SMatthew G. Knepley } 1452*b5da9499SMatthew G. Knepley /* Interior faces have 3 edges and 2 cells */ 1453*b5da9499SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1454*b5da9499SMatthew G. Knepley PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 1455*b5da9499SMatthew G. Knepley const PetscInt *cone, *ornt; 1456*b5da9499SMatthew G. Knepley PetscInt coneNew[3], orntNew[3]; 1457*b5da9499SMatthew G. Knepley PetscInt supportNew[2]; 1458*b5da9499SMatthew G. Knepley 1459*b5da9499SMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1460*b5da9499SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1461*b5da9499SMatthew G. Knepley /* Face A: {c, a, d} */ 1462*b5da9499SMatthew G. Knepley coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+0)%3 : (ornt[0]+2)%3); 1463*b5da9499SMatthew G. Knepley orntNew[0] = ornt[0] < 0 ? -2 : 0; 1464*b5da9499SMatthew G. Knepley coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+0)%3 : (ornt[1]+2)%3); 1465*b5da9499SMatthew G. Knepley orntNew[1] = ornt[1] < 0 ? -2 : 0; 1466*b5da9499SMatthew G. Knepley coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+0)%3 : (ornt[2]+2)%3); 1467*b5da9499SMatthew G. Knepley orntNew[2] = ornt[2] < 0 ? -2 : 0; 1468*b5da9499SMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1469*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1470*b5da9499SMatthew G. Knepley #if 1 1471*b5da9499SMatthew 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); 1472*b5da9499SMatthew G. Knepley for (p = 0; p < 3; ++p) { 1473*b5da9499SMatthew G. Knepley if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1474*b5da9499SMatthew G. Knepley } 1475*b5da9499SMatthew G. Knepley #endif 1476*b5da9499SMatthew G. Knepley supportNew[0] = (c - cStart)*8 + 0; 1477*b5da9499SMatthew G. Knepley supportNew[1] = (c - cStart)*8 + 0+4; 1478*b5da9499SMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1479*b5da9499SMatthew G. Knepley #if 1 1480*b5da9499SMatthew 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); 1481*b5da9499SMatthew G. Knepley for (p = 0; p < 2; ++p) { 1482*b5da9499SMatthew 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); 1483*b5da9499SMatthew G. Knepley } 1484*b5da9499SMatthew G. Knepley #endif 1485*b5da9499SMatthew G. Knepley ++newp; 1486*b5da9499SMatthew G. Knepley /* Face B: {a, b, e} */ 1487*b5da9499SMatthew G. Knepley coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+2)%3 : (ornt[0]+0)%3); 1488*b5da9499SMatthew G. Knepley orntNew[0] = ornt[0] < 0 ? -2 : 0; 1489*b5da9499SMatthew G. Knepley coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+2)%3 : (ornt[3]+0)%3); 1490*b5da9499SMatthew G. Knepley orntNew[1] = ornt[3] < 0 ? -2 : 0; 1491*b5da9499SMatthew G. Knepley coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+1)%3 : (ornt[1]+1)%3); 1492*b5da9499SMatthew G. Knepley orntNew[2] = ornt[1] < 0 ? -2 : 0; 1493*b5da9499SMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1494*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1495*b5da9499SMatthew G. Knepley #if 1 1496*b5da9499SMatthew G. Knepley if ((newp+1 < fStartNew) || (newp+1 >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+1, fStartNew, fEndNew); 1497*b5da9499SMatthew G. Knepley for (p = 0; p < 3; ++p) { 1498*b5da9499SMatthew G. Knepley if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1499*b5da9499SMatthew G. Knepley } 1500*b5da9499SMatthew G. Knepley #endif 1501*b5da9499SMatthew G. Knepley supportNew[0] = (c - cStart)*8 + 1; 1502*b5da9499SMatthew G. Knepley supportNew[1] = (c - cStart)*8 + 1+4; 1503*b5da9499SMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1504*b5da9499SMatthew G. Knepley #if 1 1505*b5da9499SMatthew 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); 1506*b5da9499SMatthew G. Knepley for (p = 0; p < 2; ++p) { 1507*b5da9499SMatthew 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); 1508*b5da9499SMatthew G. Knepley } 1509*b5da9499SMatthew G. Knepley #endif 1510*b5da9499SMatthew G. Knepley ++newp; 1511*b5da9499SMatthew G. Knepley /* Face C: {c, f, b} */ 1512*b5da9499SMatthew G. Knepley coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+2)%3 : (ornt[2]+0)%3); 1513*b5da9499SMatthew G. Knepley orntNew[0] = ornt[2] < 0 ? -2 : 0; 1514*b5da9499SMatthew G. Knepley coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+0)%3 : (ornt[3]+2)%3); 1515*b5da9499SMatthew G. Knepley orntNew[1] = ornt[3] < 0 ? -2 : 0; 1516*b5da9499SMatthew G. Knepley coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+1)%3 : (ornt[0]+1)%3); 1517*b5da9499SMatthew G. Knepley orntNew[2] = ornt[0] < 0 ? -2 : 0; 1518*b5da9499SMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1519*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1520*b5da9499SMatthew G. Knepley #if 1 1521*b5da9499SMatthew 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); 1522*b5da9499SMatthew G. Knepley for (p = 0; p < 3; ++p) { 1523*b5da9499SMatthew G. Knepley if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1524*b5da9499SMatthew G. Knepley } 1525*b5da9499SMatthew G. Knepley #endif 1526*b5da9499SMatthew G. Knepley supportNew[0] = (c - cStart)*8 + 2; 1527*b5da9499SMatthew G. Knepley supportNew[1] = (c - cStart)*8 + 2+4; 1528*b5da9499SMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1529*b5da9499SMatthew G. Knepley #if 1 1530*b5da9499SMatthew 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); 1531*b5da9499SMatthew G. Knepley for (p = 0; p < 2; ++p) { 1532*b5da9499SMatthew 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); 1533*b5da9499SMatthew G. Knepley } 1534*b5da9499SMatthew G. Knepley #endif 1535*b5da9499SMatthew G. Knepley ++newp; 1536*b5da9499SMatthew G. Knepley /* Face D: {d, e, f} */ 1537*b5da9499SMatthew G. Knepley coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+2)%3 : (ornt[1]+0)%3); 1538*b5da9499SMatthew G. Knepley orntNew[0] = ornt[1] < 0 ? -2 : 0; 1539*b5da9499SMatthew G. Knepley coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+1)%3 : (ornt[3]+1)%3); 1540*b5da9499SMatthew G. Knepley orntNew[1] = ornt[3] < 0 ? -2 : 0; 1541*b5da9499SMatthew G. Knepley coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+1)%3 : (ornt[2]+1)%3); 1542*b5da9499SMatthew G. Knepley orntNew[2] = ornt[2] < 0 ? -2 : 0; 1543*b5da9499SMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1544*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1545*b5da9499SMatthew G. Knepley #if 1 1546*b5da9499SMatthew 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); 1547*b5da9499SMatthew G. Knepley for (p = 0; p < 3; ++p) { 1548*b5da9499SMatthew G. Knepley if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1549*b5da9499SMatthew G. Knepley } 1550*b5da9499SMatthew G. Knepley #endif 1551*b5da9499SMatthew G. Knepley supportNew[0] = (c - cStart)*8 + 3; 1552*b5da9499SMatthew G. Knepley supportNew[1] = (c - cStart)*8 + 3+4; 1553*b5da9499SMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1554*b5da9499SMatthew G. Knepley #if 1 1555*b5da9499SMatthew 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); 1556*b5da9499SMatthew G. Knepley for (p = 0; p < 2; ++p) { 1557*b5da9499SMatthew 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); 1558*b5da9499SMatthew G. Knepley } 1559*b5da9499SMatthew G. Knepley #endif 1560*b5da9499SMatthew G. Knepley ++newp; 1561*b5da9499SMatthew G. Knepley /* Face E: {d, f, a} */ 1562*b5da9499SMatthew G. Knepley coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+1)%3 : (ornt[2]+1)%3); 1563*b5da9499SMatthew G. Knepley orntNew[0] = ornt[2] < 0 ? 0 : -2; 1564*b5da9499SMatthew G. Knepley coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 1565*b5da9499SMatthew G. Knepley orntNew[1] = 0; 1566*b5da9499SMatthew G. Knepley coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+0)%3 : (ornt[1]+2)%3); 1567*b5da9499SMatthew G. Knepley orntNew[2] = ornt[1] < 0 ? -2 : 0; 1568*b5da9499SMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1569*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1570*b5da9499SMatthew G. Knepley #if 1 1571*b5da9499SMatthew 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); 1572*b5da9499SMatthew G. Knepley for (p = 0; p < 3; ++p) { 1573*b5da9499SMatthew G. Knepley if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1574*b5da9499SMatthew G. Knepley } 1575*b5da9499SMatthew G. Knepley #endif 1576*b5da9499SMatthew G. Knepley supportNew[0] = (c - cStart)*8 + 0+4; 1577*b5da9499SMatthew G. Knepley supportNew[1] = (c - cStart)*8 + 3+4; 1578*b5da9499SMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1579*b5da9499SMatthew G. Knepley #if 1 1580*b5da9499SMatthew 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); 1581*b5da9499SMatthew G. Knepley for (p = 0; p < 2; ++p) { 1582*b5da9499SMatthew 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); 1583*b5da9499SMatthew G. Knepley } 1584*b5da9499SMatthew G. Knepley #endif 1585*b5da9499SMatthew G. Knepley ++newp; 1586*b5da9499SMatthew G. Knepley /* Face F: {c, a, f} */ 1587*b5da9499SMatthew G. Knepley coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+0)%3 : (ornt[0]+2)%3); 1588*b5da9499SMatthew G. Knepley orntNew[0] = ornt[0] < 0 ? -2 : 0; 1589*b5da9499SMatthew G. Knepley coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 1590*b5da9499SMatthew G. Knepley orntNew[1] = -2; 1591*b5da9499SMatthew G. Knepley coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+2)%3 : (ornt[2]+0)%3); 1592*b5da9499SMatthew G. Knepley orntNew[2] = ornt[1] < 0 ? 0 : -2; 1593*b5da9499SMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1594*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1595*b5da9499SMatthew G. Knepley #if 1 1596*b5da9499SMatthew 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); 1597*b5da9499SMatthew G. Knepley for (p = 0; p < 3; ++p) { 1598*b5da9499SMatthew G. Knepley if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1599*b5da9499SMatthew G. Knepley } 1600*b5da9499SMatthew G. Knepley #endif 1601*b5da9499SMatthew G. Knepley supportNew[0] = (c - cStart)*8 + 0+4; 1602*b5da9499SMatthew G. Knepley supportNew[1] = (c - cStart)*8 + 2+4; 1603*b5da9499SMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1604*b5da9499SMatthew G. Knepley #if 1 1605*b5da9499SMatthew 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); 1606*b5da9499SMatthew G. Knepley for (p = 0; p < 2; ++p) { 1607*b5da9499SMatthew 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); 1608*b5da9499SMatthew G. Knepley } 1609*b5da9499SMatthew G. Knepley #endif 1610*b5da9499SMatthew G. Knepley ++newp; 1611*b5da9499SMatthew G. Knepley /* Face G: {e, a, f} */ 1612*b5da9499SMatthew G. Knepley coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+1)%3 : (ornt[1]+1)%3); 1613*b5da9499SMatthew G. Knepley orntNew[0] = ornt[1] < 0 ? -2 : 0; 1614*b5da9499SMatthew G. Knepley coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 1615*b5da9499SMatthew G. Knepley orntNew[1] = -2; 1616*b5da9499SMatthew G. Knepley coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+1)%3 : (ornt[3]+1)%3); 1617*b5da9499SMatthew G. Knepley orntNew[2] = ornt[3] < 0 ? 0 : -2; 1618*b5da9499SMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1619*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1620*b5da9499SMatthew G. Knepley #if 1 1621*b5da9499SMatthew 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); 1622*b5da9499SMatthew G. Knepley for (p = 0; p < 3; ++p) { 1623*b5da9499SMatthew G. Knepley if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1624*b5da9499SMatthew G. Knepley } 1625*b5da9499SMatthew G. Knepley #endif 1626*b5da9499SMatthew G. Knepley supportNew[0] = (c - cStart)*8 + 1+4; 1627*b5da9499SMatthew G. Knepley supportNew[1] = (c - cStart)*8 + 3+4; 1628*b5da9499SMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1629*b5da9499SMatthew G. Knepley #if 1 1630*b5da9499SMatthew 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); 1631*b5da9499SMatthew G. Knepley for (p = 0; p < 2; ++p) { 1632*b5da9499SMatthew 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); 1633*b5da9499SMatthew G. Knepley } 1634*b5da9499SMatthew G. Knepley #endif 1635*b5da9499SMatthew G. Knepley ++newp; 1636*b5da9499SMatthew G. Knepley /* Face H: {a, b, f} */ 1637*b5da9499SMatthew G. Knepley coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+2)%3 : (ornt[0]+0)%3); 1638*b5da9499SMatthew G. Knepley orntNew[0] = ornt[0] < 0 ? -2 : 0; 1639*b5da9499SMatthew G. Knepley coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+0)%3 : (ornt[3]+2)%3); 1640*b5da9499SMatthew G. Knepley orntNew[1] = ornt[3] < 0 ? 0 : -2; 1641*b5da9499SMatthew G. Knepley coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 1642*b5da9499SMatthew G. Knepley orntNew[2] = 0; 1643*b5da9499SMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1644*b5da9499SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1645*b5da9499SMatthew G. Knepley #if 1 1646*b5da9499SMatthew 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); 1647*b5da9499SMatthew G. Knepley for (p = 0; p < 3; ++p) { 1648*b5da9499SMatthew G. Knepley if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1649*b5da9499SMatthew G. Knepley } 1650*b5da9499SMatthew G. Knepley #endif 1651*b5da9499SMatthew G. Knepley supportNew[0] = (c - cStart)*8 + 1+4; 1652*b5da9499SMatthew G. Knepley supportNew[1] = (c - cStart)*8 + 2+4; 1653*b5da9499SMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1654*b5da9499SMatthew G. Knepley #if 1 1655*b5da9499SMatthew 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); 1656*b5da9499SMatthew G. Knepley for (p = 0; p < 2; ++p) { 1657*b5da9499SMatthew 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); 1658*b5da9499SMatthew G. Knepley } 1659*b5da9499SMatthew G. Knepley #endif 1660*b5da9499SMatthew G. Knepley ++newp; 1661*b5da9499SMatthew G. Knepley } 1662*b5da9499SMatthew G. Knepley /* Split Edges have 2 vertices and the same faces as the parent */ 1663*b5da9499SMatthew G. Knepley for (e = eStart; e < eEnd; ++e) { 1664*b5da9499SMatthew G. Knepley const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 1665*b5da9499SMatthew G. Knepley 1666*b5da9499SMatthew G. Knepley for (r = 0; r < 2; ++r) { 1667*b5da9499SMatthew G. Knepley const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1668*b5da9499SMatthew G. Knepley const PetscInt *cone, *ornt, *support; 1669*b5da9499SMatthew G. Knepley PetscInt coneNew[2], coneSize, c, supportSize, s; 1670*b5da9499SMatthew G. Knepley 1671*b5da9499SMatthew G. Knepley ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 1672*b5da9499SMatthew G. Knepley coneNew[0] = vStartNew + (cone[0] - vStart); 1673*b5da9499SMatthew G. Knepley coneNew[1] = vStartNew + (cone[1] - vStart); 1674*b5da9499SMatthew G. Knepley coneNew[(r+1)%2] = newv; 1675*b5da9499SMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1676*b5da9499SMatthew G. Knepley #if 1 1677*b5da9499SMatthew G. Knepley if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 1678*b5da9499SMatthew G. Knepley for (p = 0; p < 2; ++p) { 1679*b5da9499SMatthew 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); 1680*b5da9499SMatthew G. Knepley } 1681*b5da9499SMatthew G. Knepley #endif 1682*b5da9499SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 1683*b5da9499SMatthew G. Knepley ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 1684*b5da9499SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 1685*b5da9499SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1686*b5da9499SMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1687*b5da9499SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1688*b5da9499SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 1689*b5da9499SMatthew G. Knepley if (cone[c] == e) break; 1690*b5da9499SMatthew G. Knepley } 1691*b5da9499SMatthew G. Knepley supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 1692*b5da9499SMatthew G. Knepley } 1693*b5da9499SMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1694*b5da9499SMatthew G. Knepley #if 1 1695*b5da9499SMatthew G. Knepley if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 1696*b5da9499SMatthew G. Knepley for (p = 0; p < supportSize; ++p) { 1697*b5da9499SMatthew 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); 1698*b5da9499SMatthew G. Knepley } 1699*b5da9499SMatthew G. Knepley #endif 1700*b5da9499SMatthew G. Knepley } 1701*b5da9499SMatthew G. Knepley } 1702*b5da9499SMatthew G. Knepley /* Face Edges have 2 vertices and 2+cells*(1/2) faces */ 1703*b5da9499SMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 1704*b5da9499SMatthew G. Knepley const PetscInt *cone, *ornt, *support; 1705*b5da9499SMatthew G. Knepley PetscInt coneSize, supportSize, s; 1706*b5da9499SMatthew G. Knepley 1707*b5da9499SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1708*b5da9499SMatthew G. Knepley ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1709*b5da9499SMatthew G. Knepley for (r = 0; r < 3; ++r) { 1710*b5da9499SMatthew G. Knepley const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 1711*b5da9499SMatthew G. Knepley PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 1712*b5da9499SMatthew G. Knepley PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 1713*b5da9499SMatthew G. Knepley -1, -1, 1, 6, 0, 4, 1714*b5da9499SMatthew G. Knepley 2, 5, 3, 4, -1, -1, 1715*b5da9499SMatthew G. Knepley -1, -1, 3, 6, 2, 7}; 1716*b5da9499SMatthew G. Knepley 1717*b5da9499SMatthew G. Knepley ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1718*b5da9499SMatthew G. Knepley coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 1719*b5da9499SMatthew G. Knepley coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 1720*b5da9499SMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1721*b5da9499SMatthew G. Knepley #if 1 1722*b5da9499SMatthew G. Knepley if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 1723*b5da9499SMatthew G. Knepley for (p = 0; p < 2; ++p) { 1724*b5da9499SMatthew 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); 1725*b5da9499SMatthew G. Knepley } 1726*b5da9499SMatthew G. Knepley #endif 1727*b5da9499SMatthew G. Knepley supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 1728*b5da9499SMatthew G. Knepley supportRef[1] = fStartNew + (f - fStart)*4 + 3; 1729*b5da9499SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 1730*b5da9499SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1731*b5da9499SMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1732*b5da9499SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1733*b5da9499SMatthew G. Knepley for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 1734*b5da9499SMatthew G. Knepley er = ornt[c] < 0 ? (-(ornt[c]+1) + r)%3 : (ornt[c] + r)%3; 1735*b5da9499SMatthew G. Knepley if (er == eint[c]) { 1736*b5da9499SMatthew G. Knepley supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 1737*b5da9499SMatthew G. Knepley } else { 1738*b5da9499SMatthew G. Knepley supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 1739*b5da9499SMatthew G. Knepley supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 1740*b5da9499SMatthew G. Knepley } 1741*b5da9499SMatthew G. Knepley } 1742*b5da9499SMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1743*b5da9499SMatthew G. Knepley #if 1 1744*b5da9499SMatthew G. Knepley if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 1745*b5da9499SMatthew G. Knepley for (p = 0; p < intFaces; ++p) { 1746*b5da9499SMatthew 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); 1747*b5da9499SMatthew G. Knepley } 1748*b5da9499SMatthew G. Knepley #endif 1749*b5da9499SMatthew G. Knepley } 1750*b5da9499SMatthew G. Knepley } 1751*b5da9499SMatthew G. Knepley /* Interior edges have 2 vertices and 4 faces */ 1752*b5da9499SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1753*b5da9499SMatthew G. Knepley const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 1754*b5da9499SMatthew G. Knepley const PetscInt *cone, *ornt, *fcone; 1755*b5da9499SMatthew G. Knepley PetscInt coneNew[2], supportNew[2], find; 1756*b5da9499SMatthew G. Knepley 1757*b5da9499SMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1758*b5da9499SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1759*b5da9499SMatthew G. Knepley ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 1760*b5da9499SMatthew G. Knepley find = ornt[0] < 0 ? (-(ornt[0]+1) + 0)%3 : ornt[0]; 1761*b5da9499SMatthew G. Knepley coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 1762*b5da9499SMatthew G. Knepley ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 1763*b5da9499SMatthew G. Knepley find = ornt[2] < 0 ? (-(ornt[2]+1) + 1)%3 : (ornt[2]+1)%3; 1764*b5da9499SMatthew G. Knepley coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 1765*b5da9499SMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1766*b5da9499SMatthew G. Knepley #if 1 1767*b5da9499SMatthew G. Knepley if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 1768*b5da9499SMatthew G. Knepley for (p = 0; p < 2; ++p) { 1769*b5da9499SMatthew 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); 1770*b5da9499SMatthew G. Knepley } 1771*b5da9499SMatthew G. Knepley #endif 1772*b5da9499SMatthew G. Knepley supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 1773*b5da9499SMatthew G. Knepley supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 1774*b5da9499SMatthew G. Knepley supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 1775*b5da9499SMatthew G. Knepley supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 1776*b5da9499SMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1777*b5da9499SMatthew G. Knepley #if 1 1778*b5da9499SMatthew G. Knepley if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 1779*b5da9499SMatthew G. Knepley for (p = 0; p < 4; ++p) { 1780*b5da9499SMatthew G. Knepley if ((supportNew[p] < fStartNew) || (supportNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportNew[p], fStartNew, fEndNew); 1781*b5da9499SMatthew G. Knepley } 1782*b5da9499SMatthew G. Knepley #endif 1783*b5da9499SMatthew G. Knepley } 1784*b5da9499SMatthew G. Knepley /* Old vertices have identical supports */ 1785*b5da9499SMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 1786*b5da9499SMatthew G. Knepley const PetscInt newp = vStartNew + (v - vStart); 1787*b5da9499SMatthew G. Knepley const PetscInt *support, *cone; 1788*b5da9499SMatthew G. Knepley PetscInt size, s; 1789*b5da9499SMatthew G. Knepley 1790*b5da9499SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1791*b5da9499SMatthew G. Knepley ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1792*b5da9499SMatthew G. Knepley for (s = 0; s < size; ++s) { 1793*b5da9499SMatthew G. Knepley PetscInt r = 0; 1794*b5da9499SMatthew G. Knepley 1795*b5da9499SMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1796*b5da9499SMatthew G. Knepley if (cone[1] == v) r = 1; 1797*b5da9499SMatthew G. Knepley supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 1798*b5da9499SMatthew G. Knepley } 1799*b5da9499SMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1800*b5da9499SMatthew G. Knepley #if 1 1801*b5da9499SMatthew 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); 1802*b5da9499SMatthew G. Knepley for (p = 0; p < size; ++p) { 1803*b5da9499SMatthew G. Knepley if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 1804*b5da9499SMatthew G. Knepley } 1805*b5da9499SMatthew G. Knepley #endif 1806*b5da9499SMatthew G. Knepley } 1807*b5da9499SMatthew G. Knepley /* Edge vertices have 2 + face*2 + 0/1 supports */ 1808*b5da9499SMatthew G. Knepley for (e = eStart; e < eEnd; ++e) { 1809*b5da9499SMatthew G. Knepley const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1810*b5da9499SMatthew G. Knepley const PetscInt *cone, *support; 1811*b5da9499SMatthew G. Knepley PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 1812*b5da9499SMatthew G. Knepley 1813*b5da9499SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1814*b5da9499SMatthew G. Knepley ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 1815*b5da9499SMatthew G. Knepley supportRef[0] = eStartNew + (e - eStart)*2 + 0; 1816*b5da9499SMatthew G. Knepley supportRef[1] = eStartNew + (e - eStart)*2 + 1; 1817*b5da9499SMatthew G. Knepley for (s = 0; s < size; ++s) { 1818*b5da9499SMatthew G. Knepley PetscInt r = 0; 1819*b5da9499SMatthew G. Knepley 1820*b5da9499SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1821*b5da9499SMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1822*b5da9499SMatthew G. Knepley for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 1823*b5da9499SMatthew G. Knepley supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 1824*b5da9499SMatthew G. Knepley supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 1825*b5da9499SMatthew G. Knepley } 1826*b5da9499SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 1827*b5da9499SMatthew G. Knepley for (s = 0; s < starSize*2; s += 2) { 1828*b5da9499SMatthew G. Knepley const PetscInt *cone, *ornt; 1829*b5da9499SMatthew G. Knepley PetscInt e01, e23; 1830*b5da9499SMatthew G. Knepley 1831*b5da9499SMatthew G. Knepley if ((star[s] >= cStart) && (star[s] < cEnd)) { 1832*b5da9499SMatthew G. Knepley /* Check edge 0-1 */ 1833*b5da9499SMatthew G. Knepley ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 1834*b5da9499SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 1835*b5da9499SMatthew G. Knepley ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 1836*b5da9499SMatthew G. Knepley e01 = cone[ornt[0] < 0 ? (-(ornt[0]+1) + 0)%3 : ornt[0]]; 1837*b5da9499SMatthew G. Knepley /* Check edge 2-3 */ 1838*b5da9499SMatthew G. Knepley ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 1839*b5da9499SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 1840*b5da9499SMatthew G. Knepley ierr = DMPlexGetCone(dm, cone[3], &cone);CHKERRQ(ierr); 1841*b5da9499SMatthew G. Knepley e23 = cone[ornt[3] < 0 ? (-(ornt[3]+1) + 2)%3 : (ornt[3] + 2)%3]; 1842*b5da9499SMatthew G. Knepley if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 1843*b5da9499SMatthew G. Knepley } 1844*b5da9499SMatthew G. Knepley } 1845*b5da9499SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 1846*b5da9499SMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1847*b5da9499SMatthew G. Knepley #if 1 1848*b5da9499SMatthew 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); 1849*b5da9499SMatthew G. Knepley for (p = 0; p < 2+size*2+cellSize; ++p) { 1850*b5da9499SMatthew G. Knepley if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 1851*b5da9499SMatthew G. Knepley } 1852*b5da9499SMatthew G. Knepley #endif 1853*b5da9499SMatthew G. Knepley } 1854*b5da9499SMatthew G. Knepley ierr = PetscFree(supportRef);CHKERRQ(ierr); 1855*b5da9499SMatthew G. Knepley ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 1856*b5da9499SMatthew G. Knepley break; 185775d3a19aSMatthew G. Knepley default: 185875d3a19aSMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 185975d3a19aSMatthew G. Knepley } 186075d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 186175d3a19aSMatthew G. Knepley } 186275d3a19aSMatthew G. Knepley 186375d3a19aSMatthew G. Knepley #undef __FUNCT__ 186475d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCoordinates" 186575d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 186675d3a19aSMatthew G. Knepley { 186775d3a19aSMatthew G. Knepley PetscSection coordSection, coordSectionNew; 186875d3a19aSMatthew G. Knepley Vec coordinates, coordinatesNew; 186975d3a19aSMatthew G. Knepley PetscScalar *coords, *coordsNew; 1870*b5da9499SMatthew G. Knepley PetscInt dim, depth, coordSizeNew, cStart, cEnd, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 187175d3a19aSMatthew G. Knepley PetscErrorCode ierr; 187275d3a19aSMatthew G. Knepley 187375d3a19aSMatthew G. Knepley PetscFunctionBegin; 187475d3a19aSMatthew G. Knepley ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 187575d3a19aSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 187675d3a19aSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1877*b5da9499SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 187875d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 187975d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 1880*b5da9499SMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, NULL, &fMax, &eMax, NULL);CHKERRQ(ierr); 188175d3a19aSMatthew G. Knepley ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr); 188275d3a19aSMatthew G. Knepley ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 188375d3a19aSMatthew G. Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 188475d3a19aSMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 188575d3a19aSMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dim);CHKERRQ(ierr); 188675d3a19aSMatthew G. Knepley ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+depthSize[0]);CHKERRQ(ierr); 188775d3a19aSMatthew G. Knepley if (fMax < 0) fMax = fEnd; 1888*b5da9499SMatthew G. Knepley if (eMax < 0) eMax = eEnd; 188975d3a19aSMatthew G. Knepley /* All vertices have the dim coordinates */ 189075d3a19aSMatthew G. Knepley for (v = vStartNew; v < vStartNew+depthSize[0]; ++v) { 189175d3a19aSMatthew G. Knepley ierr = PetscSectionSetDof(coordSectionNew, v, dim);CHKERRQ(ierr); 189275d3a19aSMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dim);CHKERRQ(ierr); 189375d3a19aSMatthew G. Knepley } 189475d3a19aSMatthew G. Knepley ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 189575d3a19aSMatthew G. Knepley ierr = DMPlexSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr); 189675d3a19aSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 189775d3a19aSMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 189875d3a19aSMatthew G. Knepley ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr); 189975d3a19aSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 190075d3a19aSMatthew G. Knepley ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 190175d3a19aSMatthew G. Knepley ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr); 190275d3a19aSMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 190375d3a19aSMatthew G. Knepley ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 1904*b5da9499SMatthew G. Knepley switch (refiner) { 1905*b5da9499SMatthew G. Knepley case 6: /* Hex 3D */ 1906*b5da9499SMatthew G. Knepley /* Face vertices have the average of corner coordinates */ 1907*b5da9499SMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 1908*b5da9499SMatthew G. Knepley const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cEnd - cStart) + (f - fStart); 1909*b5da9499SMatthew G. Knepley PetscInt *cone = NULL; 1910*b5da9499SMatthew G. Knepley PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 1911*b5da9499SMatthew G. Knepley 1912*b5da9499SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 1913*b5da9499SMatthew G. Knepley for (p = 0; p < closureSize*2; p += 2) { 1914*b5da9499SMatthew G. Knepley const PetscInt point = cone[p]; 1915*b5da9499SMatthew G. Knepley if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 1916*b5da9499SMatthew G. Knepley } 1917*b5da9499SMatthew G. Knepley for (v = 0; v < coneSize; ++v) { 1918*b5da9499SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 1919*b5da9499SMatthew G. Knepley } 1920*b5da9499SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 1921*b5da9499SMatthew G. Knepley for (d = 0; d < dim; ++d) { 1922*b5da9499SMatthew G. Knepley coordsNew[offnew+d] = 0.0; 1923*b5da9499SMatthew G. Knepley for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 1924*b5da9499SMatthew G. Knepley coordsNew[offnew+d] /= coneSize; 1925*b5da9499SMatthew G. Knepley } 1926*b5da9499SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 1927*b5da9499SMatthew G. Knepley } 1928*b5da9499SMatthew G. Knepley case 2: /* Hex 2D */ 1929*b5da9499SMatthew G. Knepley /* Cell vertices have the average of corner coordinates */ 1930*b5da9499SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1931*b5da9499SMatthew G. Knepley const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (c - cStart); 1932*b5da9499SMatthew G. Knepley PetscInt *cone = NULL; 1933*b5da9499SMatthew G. Knepley PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 1934*b5da9499SMatthew G. Knepley 1935*b5da9499SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 1936*b5da9499SMatthew G. Knepley for (p = 0; p < closureSize*2; p += 2) { 1937*b5da9499SMatthew G. Knepley const PetscInt point = cone[p]; 1938*b5da9499SMatthew G. Knepley if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 1939*b5da9499SMatthew G. Knepley } 1940*b5da9499SMatthew G. Knepley for (v = 0; v < coneSize; ++v) { 1941*b5da9499SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 1942*b5da9499SMatthew G. Knepley } 1943*b5da9499SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 1944*b5da9499SMatthew G. Knepley for (d = 0; d < dim; ++d) { 1945*b5da9499SMatthew G. Knepley coordsNew[offnew+d] = 0.0; 1946*b5da9499SMatthew G. Knepley for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 1947*b5da9499SMatthew G. Knepley coordsNew[offnew+d] /= coneSize; 1948*b5da9499SMatthew G. Knepley } 1949*b5da9499SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 1950*b5da9499SMatthew G. Knepley } 1951*b5da9499SMatthew G. Knepley case 1: /* Simplicial 2D */ 1952*b5da9499SMatthew G. Knepley case 3: /* Hybrid Simplicial 2D */ 1953*b5da9499SMatthew G. Knepley case 5: /* Simplicial 3D */ 1954*b5da9499SMatthew G. Knepley /* Edge vertices have the average of endpoint coordinates */ 1955*b5da9499SMatthew G. Knepley for (e = eStart; e < eMax; ++e) { 1956*b5da9499SMatthew G. Knepley const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 1957*b5da9499SMatthew G. Knepley const PetscInt *cone; 1958*b5da9499SMatthew G. Knepley PetscInt coneSize, offA, offB, offnew, d; 1959*b5da9499SMatthew G. Knepley 1960*b5da9499SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 1961*b5da9499SMatthew G. Knepley if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 1962*b5da9499SMatthew G. Knepley ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 1963*b5da9499SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 1964*b5da9499SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 1965*b5da9499SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 1966*b5da9499SMatthew G. Knepley for (d = 0; d < dim; ++d) { 1967*b5da9499SMatthew G. Knepley coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]); 1968*b5da9499SMatthew G. Knepley } 1969*b5da9499SMatthew G. Knepley } 197075d3a19aSMatthew G. Knepley /* Old vertices have the same coordinates */ 197175d3a19aSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 197275d3a19aSMatthew G. Knepley const PetscInt newv = vStartNew + (v - vStart); 197375d3a19aSMatthew G. Knepley PetscInt off, offnew, d; 197475d3a19aSMatthew G. Knepley 197575d3a19aSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 197675d3a19aSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 197775d3a19aSMatthew G. Knepley for (d = 0; d < dim; ++d) { 197875d3a19aSMatthew G. Knepley coordsNew[offnew+d] = coords[off+d]; 197975d3a19aSMatthew G. Knepley } 198075d3a19aSMatthew G. Knepley } 1981*b5da9499SMatthew G. Knepley break; 1982*b5da9499SMatthew G. Knepley default: 1983*b5da9499SMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 198475d3a19aSMatthew G. Knepley } 198575d3a19aSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 198675d3a19aSMatthew G. Knepley ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 198775d3a19aSMatthew G. Knepley ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 198875d3a19aSMatthew G. Knepley ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 198975d3a19aSMatthew G. Knepley ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 199075d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 199175d3a19aSMatthew G. Knepley } 199275d3a19aSMatthew G. Knepley 199375d3a19aSMatthew G. Knepley #undef __FUNCT__ 199475d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexCreateProcessSF" 199575d3a19aSMatthew G. Knepley PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 199675d3a19aSMatthew G. Knepley { 199775d3a19aSMatthew G. Knepley PetscInt numRoots, numLeaves, l; 199875d3a19aSMatthew G. Knepley const PetscInt *localPoints; 199975d3a19aSMatthew G. Knepley const PetscSFNode *remotePoints; 200075d3a19aSMatthew G. Knepley PetscInt *localPointsNew; 200175d3a19aSMatthew G. Knepley PetscSFNode *remotePointsNew; 200275d3a19aSMatthew G. Knepley PetscInt *ranks, *ranksNew; 200375d3a19aSMatthew G. Knepley PetscErrorCode ierr; 200475d3a19aSMatthew G. Knepley 200575d3a19aSMatthew G. Knepley PetscFunctionBegin; 200675d3a19aSMatthew G. Knepley ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 200775d3a19aSMatthew G. Knepley ierr = PetscMalloc(numLeaves * sizeof(PetscInt), &ranks);CHKERRQ(ierr); 200875d3a19aSMatthew G. Knepley for (l = 0; l < numLeaves; ++l) { 200975d3a19aSMatthew G. Knepley ranks[l] = remotePoints[l].rank; 201075d3a19aSMatthew G. Knepley } 201175d3a19aSMatthew G. Knepley ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 201275d3a19aSMatthew G. Knepley ierr = PetscMalloc(numLeaves * sizeof(PetscInt), &ranksNew);CHKERRQ(ierr); 201375d3a19aSMatthew G. Knepley ierr = PetscMalloc(numLeaves * sizeof(PetscInt), &localPointsNew);CHKERRQ(ierr); 201475d3a19aSMatthew G. Knepley ierr = PetscMalloc(numLeaves * sizeof(PetscSFNode), &remotePointsNew);CHKERRQ(ierr); 201575d3a19aSMatthew G. Knepley for (l = 0; l < numLeaves; ++l) { 201675d3a19aSMatthew G. Knepley ranksNew[l] = ranks[l]; 201775d3a19aSMatthew G. Knepley localPointsNew[l] = l; 201875d3a19aSMatthew G. Knepley remotePointsNew[l].index = 0; 201975d3a19aSMatthew G. Knepley remotePointsNew[l].rank = ranksNew[l]; 202075d3a19aSMatthew G. Knepley } 202175d3a19aSMatthew G. Knepley ierr = PetscFree(ranks);CHKERRQ(ierr); 202275d3a19aSMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr); 202375d3a19aSMatthew G. Knepley ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 202475d3a19aSMatthew G. Knepley ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 202575d3a19aSMatthew G. Knepley ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 202675d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 202775d3a19aSMatthew G. Knepley } 202875d3a19aSMatthew G. Knepley 202975d3a19aSMatthew G. Knepley #undef __FUNCT__ 203075d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateSF" 203175d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 203275d3a19aSMatthew G. Knepley { 203375d3a19aSMatthew G. Knepley PetscSF sf, sfNew, sfProcess; 203475d3a19aSMatthew G. Knepley IS processRanks; 203575d3a19aSMatthew G. Knepley MPI_Datatype depthType; 203675d3a19aSMatthew G. Knepley PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 203775d3a19aSMatthew G. Knepley const PetscInt *localPoints, *neighbors; 203875d3a19aSMatthew G. Knepley const PetscSFNode *remotePoints; 203975d3a19aSMatthew G. Knepley PetscInt *localPointsNew; 204075d3a19aSMatthew G. Knepley PetscSFNode *remotePointsNew; 204175d3a19aSMatthew G. Knepley PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 204275d3a19aSMatthew 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; 204375d3a19aSMatthew G. Knepley PetscErrorCode ierr; 204475d3a19aSMatthew G. Knepley 204575d3a19aSMatthew G. Knepley PetscFunctionBegin; 204675d3a19aSMatthew G. Knepley ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 204775d3a19aSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 204875d3a19aSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 204975d3a19aSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 205075d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 205175d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 205275d3a19aSMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 205375d3a19aSMatthew G. Knepley ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 205475d3a19aSMatthew G. Knepley switch (refiner) { 205575d3a19aSMatthew G. Knepley case 3: 205675d3a19aSMatthew G. Knepley if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 205775d3a19aSMatthew G. Knepley cMax = PetscMin(cEnd, cMax); 205875d3a19aSMatthew G. Knepley if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 205975d3a19aSMatthew G. Knepley fMax = PetscMin(fEnd, fMax); 206075d3a19aSMatthew G. Knepley } 206175d3a19aSMatthew G. Knepley ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 206275d3a19aSMatthew G. Knepley ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 206375d3a19aSMatthew G. Knepley /* Caculate size of new SF */ 206475d3a19aSMatthew G. Knepley ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 206575d3a19aSMatthew G. Knepley if (numRoots < 0) PetscFunctionReturn(0); 206675d3a19aSMatthew G. Knepley for (l = 0; l < numLeaves; ++l) { 206775d3a19aSMatthew G. Knepley const PetscInt p = localPoints[l]; 206875d3a19aSMatthew G. Knepley 206975d3a19aSMatthew G. Knepley switch (refiner) { 207075d3a19aSMatthew G. Knepley case 1: 207175d3a19aSMatthew G. Knepley /* Simplicial 2D */ 207275d3a19aSMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) { 207375d3a19aSMatthew G. Knepley /* Old vertices stay the same */ 207475d3a19aSMatthew G. Knepley ++numLeavesNew; 207575d3a19aSMatthew G. Knepley } else if ((p >= fStart) && (p < fEnd)) { 207675d3a19aSMatthew G. Knepley /* Old faces add new faces and vertex */ 2077d963de37SMatthew G. Knepley numLeavesNew += 2 + 1; 207875d3a19aSMatthew G. Knepley } else if ((p >= cStart) && (p < cEnd)) { 207975d3a19aSMatthew G. Knepley /* Old cells add new cells and interior faces */ 208075d3a19aSMatthew G. Knepley numLeavesNew += 4 + 3; 208175d3a19aSMatthew G. Knepley } 208275d3a19aSMatthew G. Knepley break; 208375d3a19aSMatthew G. Knepley case 2: 208475d3a19aSMatthew G. Knepley /* Hex 2D */ 208575d3a19aSMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) { 208675d3a19aSMatthew G. Knepley /* Old vertices stay the same */ 208775d3a19aSMatthew G. Knepley ++numLeavesNew; 208875d3a19aSMatthew G. Knepley } else if ((p >= fStart) && (p < fEnd)) { 208975d3a19aSMatthew G. Knepley /* Old faces add new faces and vertex */ 2090d963de37SMatthew G. Knepley numLeavesNew += 2 + 1; 209175d3a19aSMatthew G. Knepley } else if ((p >= cStart) && (p < cEnd)) { 209275d3a19aSMatthew G. Knepley /* Old cells add new cells and interior faces */ 209375d3a19aSMatthew G. Knepley numLeavesNew += 4 + 4; 209475d3a19aSMatthew G. Knepley } 209575d3a19aSMatthew G. Knepley break; 2096*b5da9499SMatthew G. Knepley case 5: 2097*b5da9499SMatthew G. Knepley /* Simplicial 3D */ 2098*b5da9499SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) { 2099*b5da9499SMatthew G. Knepley /* Old vertices stay the same */ 2100*b5da9499SMatthew G. Knepley ++numLeavesNew; 2101*b5da9499SMatthew G. Knepley } else if ((p >= eStart) && (p < eEnd)) { 2102*b5da9499SMatthew G. Knepley /* Old edges add new edges and vertex */ 2103*b5da9499SMatthew G. Knepley numLeavesNew += 2 + 1; 2104*b5da9499SMatthew G. Knepley } else if ((p >= fStart) && (p < fEnd)) { 2105*b5da9499SMatthew G. Knepley /* Old faces add new faces and face edges */ 2106*b5da9499SMatthew G. Knepley numLeavesNew += 4 + 3; 2107*b5da9499SMatthew G. Knepley } else if ((p >= cStart) && (p < cEnd)) { 2108*b5da9499SMatthew G. Knepley /* Old cells add new cells and interior faces and edges */ 2109*b5da9499SMatthew G. Knepley numLeavesNew += 8 + 8 + 1; 2110*b5da9499SMatthew G. Knepley } 2111*b5da9499SMatthew G. Knepley break; 211275d3a19aSMatthew G. Knepley default: 211375d3a19aSMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 211475d3a19aSMatthew G. Knepley } 211575d3a19aSMatthew G. Knepley } 211675d3a19aSMatthew G. Knepley /* Communicate depthSizes for each remote rank */ 211775d3a19aSMatthew G. Knepley ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 211875d3a19aSMatthew G. Knepley ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 211975d3a19aSMatthew G. Knepley ierr = PetscMalloc5((depth+1)*numNeighbors,PetscInt,&rdepthSize,numNeighbors,PetscInt,&rvStartNew,numNeighbors,PetscInt,&reStartNew,numNeighbors,PetscInt,&rfStartNew,numNeighbors,PetscInt,&rcStartNew);CHKERRQ(ierr); 212075d3a19aSMatthew 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); 212175d3a19aSMatthew G. Knepley ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 212275d3a19aSMatthew G. Knepley ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 212375d3a19aSMatthew G. Knepley ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 212475d3a19aSMatthew G. Knepley ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 212575d3a19aSMatthew G. Knepley for (n = 0; n < numNeighbors; ++n) { 212675d3a19aSMatthew G. Knepley ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 212775d3a19aSMatthew G. Knepley } 212875d3a19aSMatthew G. Knepley depthSizeOld[depth] = cMax; 212975d3a19aSMatthew G. Knepley depthSizeOld[0] = vMax; 213075d3a19aSMatthew G. Knepley depthSizeOld[depth-1] = fMax; 213175d3a19aSMatthew G. Knepley depthSizeOld[1] = eMax; 213275d3a19aSMatthew G. Knepley 213375d3a19aSMatthew G. Knepley ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 213475d3a19aSMatthew G. Knepley ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 213575d3a19aSMatthew G. Knepley 213675d3a19aSMatthew G. Knepley depthSizeOld[depth] = cEnd - cStart; 213775d3a19aSMatthew G. Knepley depthSizeOld[0] = vEnd - vStart; 213875d3a19aSMatthew G. Knepley depthSizeOld[depth-1] = fEnd - fStart; 213975d3a19aSMatthew G. Knepley depthSizeOld[1] = eEnd - eStart; 214075d3a19aSMatthew G. Knepley 214175d3a19aSMatthew G. Knepley ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 214275d3a19aSMatthew G. Knepley ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 214375d3a19aSMatthew G. Knepley for (n = 0; n < numNeighbors; ++n) { 214475d3a19aSMatthew G. Knepley ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 214575d3a19aSMatthew G. Knepley } 214675d3a19aSMatthew G. Knepley ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 214775d3a19aSMatthew G. Knepley ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 214875d3a19aSMatthew G. Knepley /* Calculate new point SF */ 214975d3a19aSMatthew G. Knepley ierr = PetscMalloc(numLeavesNew * sizeof(PetscInt), &localPointsNew);CHKERRQ(ierr); 215075d3a19aSMatthew G. Knepley ierr = PetscMalloc(numLeavesNew * sizeof(PetscSFNode), &remotePointsNew);CHKERRQ(ierr); 215175d3a19aSMatthew G. Knepley ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 215275d3a19aSMatthew G. Knepley for (l = 0, m = 0; l < numLeaves; ++l) { 215375d3a19aSMatthew G. Knepley PetscInt p = localPoints[l]; 215475d3a19aSMatthew G. Knepley PetscInt rp = remotePoints[l].index, n; 215575d3a19aSMatthew G. Knepley PetscMPIInt rrank = remotePoints[l].rank; 215675d3a19aSMatthew G. Knepley 215775d3a19aSMatthew G. Knepley ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 215875d3a19aSMatthew G. Knepley if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 215975d3a19aSMatthew G. Knepley switch (refiner) { 216075d3a19aSMatthew G. Knepley case 1: 216175d3a19aSMatthew G. Knepley /* Simplicial 2D */ 216275d3a19aSMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) { 216375d3a19aSMatthew G. Knepley /* Old vertices stay the same */ 216475d3a19aSMatthew G. Knepley localPointsNew[m] = vStartNew + (p - vStart); 216575d3a19aSMatthew G. Knepley remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 216675d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 216775d3a19aSMatthew G. Knepley ++m; 216875d3a19aSMatthew G. Knepley } else if ((p >= fStart) && (p < fEnd)) { 216975d3a19aSMatthew G. Knepley /* Old faces add new faces and vertex */ 217075d3a19aSMatthew G. Knepley localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 217175d3a19aSMatthew G. Knepley remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 217275d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 217375d3a19aSMatthew G. Knepley ++m; 217475d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r, ++m) { 217575d3a19aSMatthew G. Knepley localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 217675d3a19aSMatthew G. Knepley remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 217775d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 217875d3a19aSMatthew G. Knepley } 217975d3a19aSMatthew G. Knepley } else if ((p >= cStart) && (p < cEnd)) { 218075d3a19aSMatthew G. Knepley /* Old cells add new cells and interior faces */ 218175d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r, ++m) { 218275d3a19aSMatthew G. Knepley localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 218375d3a19aSMatthew G. Knepley remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 218475d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 218575d3a19aSMatthew G. Knepley } 218675d3a19aSMatthew G. Knepley for (r = 0; r < 3; ++r, ++m) { 218775d3a19aSMatthew G. Knepley localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 218875d3a19aSMatthew G. Knepley remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 218975d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 219075d3a19aSMatthew G. Knepley } 219175d3a19aSMatthew G. Knepley } 219275d3a19aSMatthew G. Knepley break; 219375d3a19aSMatthew G. Knepley case 2: 219475d3a19aSMatthew G. Knepley /* Hex 2D */ 219575d3a19aSMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) { 219675d3a19aSMatthew G. Knepley /* Old vertices stay the same */ 219775d3a19aSMatthew G. Knepley localPointsNew[m] = vStartNew + (p - vStart); 219875d3a19aSMatthew G. Knepley remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 219975d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 220075d3a19aSMatthew G. Knepley ++m; 220175d3a19aSMatthew G. Knepley } else if ((p >= fStart) && (p < fEnd)) { 220275d3a19aSMatthew G. Knepley /* Old faces add new faces and vertex */ 220375d3a19aSMatthew G. Knepley localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 220475d3a19aSMatthew G. Knepley remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 220575d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 220675d3a19aSMatthew G. Knepley ++m; 220775d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r, ++m) { 220875d3a19aSMatthew G. Knepley localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 220975d3a19aSMatthew G. Knepley remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 221075d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 221175d3a19aSMatthew G. Knepley } 221275d3a19aSMatthew G. Knepley } else if ((p >= cStart) && (p < cEnd)) { 221375d3a19aSMatthew G. Knepley /* Old cells add new cells and interior faces */ 221475d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r, ++m) { 221575d3a19aSMatthew G. Knepley localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 221675d3a19aSMatthew G. Knepley remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 221775d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 221875d3a19aSMatthew G. Knepley } 221975d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r, ++m) { 222075d3a19aSMatthew G. Knepley localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 222175d3a19aSMatthew G. Knepley remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r; 222275d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 222375d3a19aSMatthew G. Knepley } 222475d3a19aSMatthew G. Knepley } 222575d3a19aSMatthew G. Knepley break; 222675d3a19aSMatthew G. Knepley case 3: 222775d3a19aSMatthew G. Knepley /* Hybrid simplicial 2D */ 222875d3a19aSMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) { 222975d3a19aSMatthew G. Knepley /* Old vertices stay the same */ 223075d3a19aSMatthew G. Knepley localPointsNew[m] = vStartNew + (p - vStart); 223175d3a19aSMatthew G. Knepley remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 223275d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 223375d3a19aSMatthew G. Knepley ++m; 223475d3a19aSMatthew G. Knepley } else if ((p >= fStart) && (p < fMax)) { 223575d3a19aSMatthew G. Knepley /* Old interior faces add new faces and vertex */ 223675d3a19aSMatthew G. Knepley localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 223775d3a19aSMatthew G. Knepley remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 223875d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 223975d3a19aSMatthew G. Knepley ++m; 224075d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r, ++m) { 224175d3a19aSMatthew G. Knepley localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 224275d3a19aSMatthew G. Knepley remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 224375d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 224475d3a19aSMatthew G. Knepley } 224575d3a19aSMatthew G. Knepley } else if ((p >= fMax) && (p < fEnd)) { 224675d3a19aSMatthew G. Knepley /* Old hybrid faces stay the same */ 224775d3a19aSMatthew G. Knepley localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 224875d3a19aSMatthew G. Knepley remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 224975d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 225075d3a19aSMatthew G. Knepley ++m; 225175d3a19aSMatthew G. Knepley } else if ((p >= cStart) && (p < cMax)) { 225275d3a19aSMatthew G. Knepley /* Old interior cells add new cells and interior faces */ 225375d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r, ++m) { 225475d3a19aSMatthew G. Knepley localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 225575d3a19aSMatthew G. Knepley remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 225675d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 225775d3a19aSMatthew G. Knepley } 225875d3a19aSMatthew G. Knepley for (r = 0; r < 3; ++r, ++m) { 225975d3a19aSMatthew G. Knepley localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 226075d3a19aSMatthew G. Knepley remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 226175d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 226275d3a19aSMatthew G. Knepley } 226375d3a19aSMatthew G. Knepley } else if ((p >= cStart) && (p < cMax)) { 226475d3a19aSMatthew G. Knepley /* Old hybrid cells add new cells and hybrid face */ 226575d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r, ++m) { 226675d3a19aSMatthew G. Knepley localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 226775d3a19aSMatthew G. Knepley remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 226875d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 226975d3a19aSMatthew G. Knepley } 227075d3a19aSMatthew G. Knepley localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 227175d3a19aSMatthew 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]); 227275d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 227375d3a19aSMatthew G. Knepley ++m; 227475d3a19aSMatthew G. Knepley } 227575d3a19aSMatthew G. Knepley break; 2276*b5da9499SMatthew G. Knepley case 5: 2277*b5da9499SMatthew G. Knepley /* Simplicial 3D */ 2278*b5da9499SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) { 2279*b5da9499SMatthew G. Knepley /* Old vertices stay the same */ 2280*b5da9499SMatthew G. Knepley localPointsNew[m] = vStartNew + (p - vStart); 2281*b5da9499SMatthew G. Knepley remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 2282*b5da9499SMatthew G. Knepley remotePointsNew[m].rank = rrank; 2283*b5da9499SMatthew G. Knepley ++m; 2284*b5da9499SMatthew G. Knepley } else if ((p >= fStart) && (p < fEnd)) { 2285*b5da9499SMatthew G. Knepley /* Old edges add new edges and vertex */ 2286*b5da9499SMatthew G. Knepley for (r = 0; r < 2; ++r, ++m) { 2287*b5da9499SMatthew G. Knepley localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 2288*b5da9499SMatthew G. Knepley remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 2289*b5da9499SMatthew G. Knepley remotePointsNew[m].rank = rrank; 2290*b5da9499SMatthew G. Knepley } 2291*b5da9499SMatthew G. Knepley localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 2292*b5da9499SMatthew G. Knepley remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 2293*b5da9499SMatthew G. Knepley remotePointsNew[m].rank = rrank; 2294*b5da9499SMatthew G. Knepley ++m; 2295*b5da9499SMatthew G. Knepley } else if ((p >= fStart) && (p < fEnd)) { 2296*b5da9499SMatthew G. Knepley /* Old faces add new faces and face edges */ 2297*b5da9499SMatthew G. Knepley for (r = 0; r < 4; ++r, ++m) { 2298*b5da9499SMatthew G. Knepley localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 2299*b5da9499SMatthew G. Knepley remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 2300*b5da9499SMatthew G. Knepley remotePointsNew[m].rank = rrank; 2301*b5da9499SMatthew G. Knepley } 2302*b5da9499SMatthew G. Knepley for (r = 0; r < 3; ++r, ++m) { 2303*b5da9499SMatthew G. Knepley localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 2304*b5da9499SMatthew G. Knepley remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*3 + r; 2305*b5da9499SMatthew G. Knepley remotePointsNew[m].rank = rrank; 2306*b5da9499SMatthew G. Knepley } 2307*b5da9499SMatthew G. Knepley } else if ((p >= cStart) && (p < cEnd)) { 2308*b5da9499SMatthew G. Knepley /* Old cells add new cells and interior faces and edges */ 2309*b5da9499SMatthew G. Knepley for (r = 0; r < 8; ++r, ++m) { 2310*b5da9499SMatthew G. Knepley localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 2311*b5da9499SMatthew G. Knepley remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 2312*b5da9499SMatthew G. Knepley remotePointsNew[m].rank = rrank; 2313*b5da9499SMatthew G. Knepley } 2314*b5da9499SMatthew G. Knepley for (r = 0; r < 8; ++r, ++m) { 2315*b5da9499SMatthew G. Knepley localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 2316*b5da9499SMatthew G. Knepley remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*8 + r; 2317*b5da9499SMatthew G. Knepley remotePointsNew[m].rank = rrank; 2318*b5da9499SMatthew G. Knepley } 2319*b5da9499SMatthew G. Knepley for (r = 0; r < 1; ++r, ++m) { 2320*b5da9499SMatthew G. Knepley localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 2321*b5da9499SMatthew G. Knepley remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*1 + r; 2322*b5da9499SMatthew G. Knepley remotePointsNew[m].rank = rrank; 2323*b5da9499SMatthew G. Knepley } 2324*b5da9499SMatthew G. Knepley } 2325*b5da9499SMatthew G. Knepley break; 232675d3a19aSMatthew G. Knepley default: 232775d3a19aSMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 232875d3a19aSMatthew G. Knepley } 232975d3a19aSMatthew G. Knepley } 233075d3a19aSMatthew G. Knepley ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 233175d3a19aSMatthew G. Knepley ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 233275d3a19aSMatthew G. Knepley ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 233375d3a19aSMatthew G. Knepley ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 233475d3a19aSMatthew G. Knepley ierr = PetscFree6(depthSizeOld,rdepthSizeOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 233575d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 233675d3a19aSMatthew G. Knepley } 233775d3a19aSMatthew G. Knepley 233875d3a19aSMatthew G. Knepley #undef __FUNCT__ 233975d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateLabels" 234075d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 234175d3a19aSMatthew G. Knepley { 234275d3a19aSMatthew G. Knepley PetscInt numLabels, l; 2343*b5da9499SMatthew G. Knepley PetscInt depth, newp, cStart, cStartNew, cEnd, cMax, vStart, vStartNew, vEnd, vMax, fStart, fStartNew, fEnd, fMax, eStart, eStartNew, eEnd, eMax, r; 234475d3a19aSMatthew G. Knepley PetscErrorCode ierr; 234575d3a19aSMatthew G. Knepley 234675d3a19aSMatthew G. Knepley PetscFunctionBegin; 234775d3a19aSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 234875d3a19aSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 234975d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 235075d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 2351d963de37SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 2352d963de37SMatthew G. Knepley ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 235375d3a19aSMatthew G. Knepley ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 235475d3a19aSMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 235575d3a19aSMatthew G. Knepley switch (refiner) { 235675d3a19aSMatthew G. Knepley case 3: 235775d3a19aSMatthew G. Knepley if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 235875d3a19aSMatthew G. Knepley cMax = PetscMin(cEnd, cMax); 235975d3a19aSMatthew G. Knepley if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 236075d3a19aSMatthew G. Knepley fMax = PetscMin(fEnd, fMax); 236175d3a19aSMatthew G. Knepley } 236275d3a19aSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 236375d3a19aSMatthew G. Knepley DMLabel label, labelNew; 236475d3a19aSMatthew G. Knepley const char *lname; 236575d3a19aSMatthew G. Knepley PetscBool isDepth; 236675d3a19aSMatthew G. Knepley IS valueIS; 236775d3a19aSMatthew G. Knepley const PetscInt *values; 236875d3a19aSMatthew G. Knepley PetscInt numValues, val; 236975d3a19aSMatthew G. Knepley 237075d3a19aSMatthew G. Knepley ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr); 237175d3a19aSMatthew G. Knepley ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 237275d3a19aSMatthew G. Knepley if (isDepth) continue; 237375d3a19aSMatthew G. Knepley ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr); 237475d3a19aSMatthew G. Knepley ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr); 237575d3a19aSMatthew G. Knepley ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 237675d3a19aSMatthew G. Knepley ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 237775d3a19aSMatthew G. Knepley ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 237875d3a19aSMatthew G. Knepley ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 237975d3a19aSMatthew G. Knepley for (val = 0; val < numValues; ++val) { 238075d3a19aSMatthew G. Knepley IS pointIS; 238175d3a19aSMatthew G. Knepley const PetscInt *points; 238275d3a19aSMatthew G. Knepley PetscInt numPoints, n; 238375d3a19aSMatthew G. Knepley 238475d3a19aSMatthew G. Knepley ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 238575d3a19aSMatthew G. Knepley ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 238675d3a19aSMatthew G. Knepley ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 238775d3a19aSMatthew G. Knepley for (n = 0; n < numPoints; ++n) { 238875d3a19aSMatthew G. Knepley const PetscInt p = points[n]; 238975d3a19aSMatthew G. Knepley switch (refiner) { 239075d3a19aSMatthew G. Knepley case 1: 239175d3a19aSMatthew G. Knepley /* Simplicial 2D */ 239275d3a19aSMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) { 239375d3a19aSMatthew G. Knepley /* Old vertices stay the same */ 239475d3a19aSMatthew G. Knepley newp = vStartNew + (p - vStart); 239575d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 239675d3a19aSMatthew G. Knepley } else if ((p >= fStart) && (p < fEnd)) { 239775d3a19aSMatthew G. Knepley /* Old faces add new faces and vertex */ 239875d3a19aSMatthew G. Knepley newp = vStartNew + (vEnd - vStart) + (p - fStart); 239975d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 240075d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 240175d3a19aSMatthew G. Knepley newp = fStartNew + (p - fStart)*2 + r; 240275d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 240375d3a19aSMatthew G. Knepley } 240475d3a19aSMatthew G. Knepley } else if ((p >= cStart) && (p < cEnd)) { 240575d3a19aSMatthew G. Knepley /* Old cells add new cells and interior faces */ 240675d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r) { 240775d3a19aSMatthew G. Knepley newp = cStartNew + (p - cStart)*4 + r; 240875d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 240975d3a19aSMatthew G. Knepley } 241075d3a19aSMatthew G. Knepley for (r = 0; r < 3; ++r) { 241175d3a19aSMatthew G. Knepley newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 241275d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 241375d3a19aSMatthew G. Knepley } 241475d3a19aSMatthew G. Knepley } 241575d3a19aSMatthew G. Knepley break; 241675d3a19aSMatthew G. Knepley case 2: 241775d3a19aSMatthew G. Knepley /* Hex 2D */ 241875d3a19aSMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) { 241975d3a19aSMatthew G. Knepley /* Old vertices stay the same */ 242075d3a19aSMatthew G. Knepley newp = vStartNew + (p - vStart); 242175d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 242275d3a19aSMatthew G. Knepley } else if ((p >= fStart) && (p < fEnd)) { 242375d3a19aSMatthew G. Knepley /* Old faces add new faces and vertex */ 242475d3a19aSMatthew G. Knepley newp = vStartNew + (vEnd - vStart) + (p - fStart); 242575d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 242675d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 242775d3a19aSMatthew G. Knepley newp = fStartNew + (p - fStart)*2 + r; 242875d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 242975d3a19aSMatthew G. Knepley } 243075d3a19aSMatthew G. Knepley } else if ((p >= cStart) && (p < cEnd)) { 243175d3a19aSMatthew G. Knepley /* Old cells add new cells and interior faces and vertex */ 243275d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r) { 243375d3a19aSMatthew G. Knepley newp = cStartNew + (p - cStart)*4 + r; 243475d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 243575d3a19aSMatthew G. Knepley } 243675d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r) { 243775d3a19aSMatthew G. Knepley newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 243875d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 243975d3a19aSMatthew G. Knepley } 244075d3a19aSMatthew G. Knepley newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 244175d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 244275d3a19aSMatthew G. Knepley } 244375d3a19aSMatthew G. Knepley break; 244475d3a19aSMatthew G. Knepley case 3: 244575d3a19aSMatthew G. Knepley /* Hybrid simplicial 2D */ 244675d3a19aSMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) { 244775d3a19aSMatthew G. Knepley /* Old vertices stay the same */ 244875d3a19aSMatthew G. Knepley newp = vStartNew + (p - vStart); 244975d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 245075d3a19aSMatthew G. Knepley } else if ((p >= fStart) && (p < fMax)) { 245175d3a19aSMatthew G. Knepley /* Old interior faces add new faces and vertex */ 245275d3a19aSMatthew G. Knepley newp = vStartNew + (vEnd - vStart) + (p - fStart); 245375d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 245475d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 245575d3a19aSMatthew G. Knepley newp = fStartNew + (p - fStart)*2 + r; 245675d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 245775d3a19aSMatthew G. Knepley } 245875d3a19aSMatthew G. Knepley } else if ((p >= fMax) && (p < fEnd)) { 245975d3a19aSMatthew G. Knepley /* Old hybrid faces stay the same */ 246075d3a19aSMatthew G. Knepley newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 246175d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 246275d3a19aSMatthew G. Knepley } else if ((p >= cStart) && (p < cMax)) { 246375d3a19aSMatthew G. Knepley /* Old interior cells add new cells and interior faces */ 246475d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r) { 246575d3a19aSMatthew G. Knepley newp = cStartNew + (p - cStart)*4 + r; 246675d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 246775d3a19aSMatthew G. Knepley } 246875d3a19aSMatthew G. Knepley for (r = 0; r < 3; ++r) { 246975d3a19aSMatthew G. Knepley newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 247075d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 247175d3a19aSMatthew G. Knepley } 247275d3a19aSMatthew G. Knepley } else if ((p >= cMax) && (p < cEnd)) { 247375d3a19aSMatthew G. Knepley /* Old hybrid cells add new cells and hybrid face */ 247475d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 247575d3a19aSMatthew G. Knepley newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 247675d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 247775d3a19aSMatthew G. Knepley } 247875d3a19aSMatthew G. Knepley newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 247975d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 248075d3a19aSMatthew G. Knepley } 248175d3a19aSMatthew G. Knepley break; 2482*b5da9499SMatthew G. Knepley case 5: 2483*b5da9499SMatthew G. Knepley /* Simplicial 3D */ 2484*b5da9499SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) { 2485*b5da9499SMatthew G. Knepley /* Old vertices stay the same */ 2486*b5da9499SMatthew G. Knepley newp = vStartNew + (p - vStart); 2487*b5da9499SMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 2488*b5da9499SMatthew G. Knepley } else if ((p >= eStart) && (p < eEnd)) { 2489*b5da9499SMatthew G. Knepley /* Old edges add new edges and vertex */ 2490*b5da9499SMatthew G. Knepley for (r = 0; r < 2; ++r) { 2491*b5da9499SMatthew G. Knepley newp = eStartNew + (p - eStart)*2 + r; 2492*b5da9499SMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 2493*b5da9499SMatthew G. Knepley } 2494*b5da9499SMatthew G. Knepley newp = vStartNew + (vEnd - vStart) + (p - eStart); 2495*b5da9499SMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 2496*b5da9499SMatthew G. Knepley } else if ((p >= fStart) && (p < fEnd)) { 2497*b5da9499SMatthew G. Knepley /* Old faces add new faces and edges */ 2498*b5da9499SMatthew G. Knepley for (r = 0; r < 4; ++r) { 2499*b5da9499SMatthew G. Knepley newp = fStartNew + (p - fStart)*4 + r; 2500*b5da9499SMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 2501*b5da9499SMatthew G. Knepley } 2502*b5da9499SMatthew G. Knepley for (r = 0; r < 3; ++r) { 2503*b5da9499SMatthew G. Knepley newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 2504*b5da9499SMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 2505*b5da9499SMatthew G. Knepley } 2506*b5da9499SMatthew G. Knepley } else if ((p >= cStart) && (p < cEnd)) { 2507*b5da9499SMatthew G. Knepley /* Old cells add new cells and interior faces and edges */ 2508*b5da9499SMatthew G. Knepley for (r = 0; r < 8; ++r) { 2509*b5da9499SMatthew G. Knepley newp = cStartNew + (p - cStart)*8 + r; 2510*b5da9499SMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 2511*b5da9499SMatthew G. Knepley } 2512*b5da9499SMatthew G. Knepley for (r = 0; r < 8; ++r) { 2513*b5da9499SMatthew G. Knepley newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 2514*b5da9499SMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 2515*b5da9499SMatthew G. Knepley } 2516*b5da9499SMatthew G. Knepley for (r = 0; r < 1; ++r) { 2517*b5da9499SMatthew G. Knepley newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 2518*b5da9499SMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 2519*b5da9499SMatthew G. Knepley } 2520*b5da9499SMatthew G. Knepley } 2521*b5da9499SMatthew G. Knepley break; 252275d3a19aSMatthew G. Knepley default: 252375d3a19aSMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 252475d3a19aSMatthew G. Knepley } 252575d3a19aSMatthew G. Knepley } 252675d3a19aSMatthew G. Knepley ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 252775d3a19aSMatthew G. Knepley ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 252875d3a19aSMatthew G. Knepley } 252975d3a19aSMatthew G. Knepley ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 253075d3a19aSMatthew G. Knepley ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 253175d3a19aSMatthew G. Knepley if (0) { 253275d3a19aSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr); 253375d3a19aSMatthew G. Knepley ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 253475d3a19aSMatthew G. Knepley ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 253575d3a19aSMatthew G. Knepley } 253675d3a19aSMatthew G. Knepley } 253775d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 253875d3a19aSMatthew G. Knepley } 253975d3a19aSMatthew G. Knepley 254075d3a19aSMatthew G. Knepley #undef __FUNCT__ 2541509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexRefineUniform_Internal" 254275d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */ 2543509c9b89SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 254475d3a19aSMatthew G. Knepley { 254575d3a19aSMatthew G. Knepley DM rdm; 254675d3a19aSMatthew G. Knepley PetscInt *depthSize; 254775d3a19aSMatthew G. Knepley PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 254875d3a19aSMatthew G. Knepley PetscErrorCode ierr; 254975d3a19aSMatthew G. Knepley 255075d3a19aSMatthew G. Knepley PetscFunctionBegin; 255175d3a19aSMatthew G. Knepley ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 255275d3a19aSMatthew G. Knepley ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 255375d3a19aSMatthew G. Knepley ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 255475d3a19aSMatthew G. Knepley ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr); 255575d3a19aSMatthew G. Knepley /* Calculate number of new points of each depth */ 255675d3a19aSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 255775d3a19aSMatthew G. Knepley ierr = PetscMalloc((depth+1) * sizeof(PetscInt), &depthSize);CHKERRQ(ierr); 255875d3a19aSMatthew G. Knepley ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 255975d3a19aSMatthew G. Knepley ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 256075d3a19aSMatthew G. Knepley /* Step 1: Set chart */ 256175d3a19aSMatthew G. Knepley for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 256275d3a19aSMatthew G. Knepley ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 256375d3a19aSMatthew G. Knepley /* Step 2: Set cone/support sizes */ 256475d3a19aSMatthew G. Knepley ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 256575d3a19aSMatthew G. Knepley /* Step 3: Setup refined DM */ 256675d3a19aSMatthew G. Knepley ierr = DMSetUp(rdm);CHKERRQ(ierr); 256775d3a19aSMatthew G. Knepley /* Step 4: Set cones and supports */ 256875d3a19aSMatthew G. Knepley ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 256975d3a19aSMatthew G. Knepley /* Step 5: Stratify */ 257075d3a19aSMatthew G. Knepley ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 257175d3a19aSMatthew G. Knepley /* Step 6: Set coordinates for vertices */ 257275d3a19aSMatthew G. Knepley ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 257375d3a19aSMatthew G. Knepley /* Step 7: Create pointSF */ 257475d3a19aSMatthew G. Knepley ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 257575d3a19aSMatthew G. Knepley /* Step 8: Create labels */ 257675d3a19aSMatthew G. Knepley ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 257775d3a19aSMatthew G. Knepley ierr = PetscFree(depthSize);CHKERRQ(ierr); 257875d3a19aSMatthew G. Knepley 257975d3a19aSMatthew G. Knepley *dmRefined = rdm; 258075d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 258175d3a19aSMatthew G. Knepley } 258275d3a19aSMatthew G. Knepley 258375d3a19aSMatthew G. Knepley #undef __FUNCT__ 258475d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementUniform" 258575d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 258675d3a19aSMatthew G. Knepley { 258775d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 258875d3a19aSMatthew G. Knepley 258975d3a19aSMatthew G. Knepley PetscFunctionBegin; 259075d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 259175d3a19aSMatthew G. Knepley mesh->refinementUniform = refinementUniform; 259275d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 259375d3a19aSMatthew G. Knepley } 259475d3a19aSMatthew G. Knepley 259575d3a19aSMatthew G. Knepley #undef __FUNCT__ 259675d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementUniform" 259775d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 259875d3a19aSMatthew G. Knepley { 259975d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 260075d3a19aSMatthew G. Knepley 260175d3a19aSMatthew G. Knepley PetscFunctionBegin; 260275d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 260375d3a19aSMatthew G. Knepley PetscValidPointer(refinementUniform, 2); 260475d3a19aSMatthew G. Knepley *refinementUniform = mesh->refinementUniform; 260575d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 260675d3a19aSMatthew G. Knepley } 260775d3a19aSMatthew G. Knepley 260875d3a19aSMatthew G. Knepley #undef __FUNCT__ 260975d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementLimit" 261075d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 261175d3a19aSMatthew G. Knepley { 261275d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 261375d3a19aSMatthew G. Knepley 261475d3a19aSMatthew G. Knepley PetscFunctionBegin; 261575d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 261675d3a19aSMatthew G. Knepley mesh->refinementLimit = refinementLimit; 261775d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 261875d3a19aSMatthew G. Knepley } 261975d3a19aSMatthew G. Knepley 262075d3a19aSMatthew G. Knepley #undef __FUNCT__ 262175d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementLimit" 262275d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 262375d3a19aSMatthew G. Knepley { 262475d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 262575d3a19aSMatthew G. Knepley 262675d3a19aSMatthew G. Knepley PetscFunctionBegin; 262775d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 262875d3a19aSMatthew G. Knepley PetscValidPointer(refinementLimit, 2); 262975d3a19aSMatthew G. Knepley /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 263075d3a19aSMatthew G. Knepley *refinementLimit = mesh->refinementLimit; 263175d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 263275d3a19aSMatthew G. Knepley } 263375d3a19aSMatthew G. Knepley 263475d3a19aSMatthew G. Knepley #undef __FUNCT__ 2635509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexGetCellRefiner_Internal" 2636509c9b89SMatthew G. Knepley PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 263775d3a19aSMatthew G. Knepley { 263875d3a19aSMatthew G. Knepley PetscInt dim, cStart, coneSize, cMax; 263975d3a19aSMatthew G. Knepley PetscErrorCode ierr; 264075d3a19aSMatthew G. Knepley 264175d3a19aSMatthew G. Knepley PetscFunctionBegin; 264275d3a19aSMatthew G. Knepley ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 264375d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, NULL);CHKERRQ(ierr); 264475d3a19aSMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 264575d3a19aSMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 264675d3a19aSMatthew G. Knepley switch (dim) { 264775d3a19aSMatthew G. Knepley case 2: 264875d3a19aSMatthew G. Knepley switch (coneSize) { 264975d3a19aSMatthew G. Knepley case 3: 265075d3a19aSMatthew G. Knepley if (cMax >= 0) *cellRefiner = 3; /* Hybrid */ 265175d3a19aSMatthew G. Knepley else *cellRefiner = 1; /* Triangular */ 265275d3a19aSMatthew G. Knepley break; 265375d3a19aSMatthew G. Knepley case 4: 265475d3a19aSMatthew G. Knepley if (cMax >= 0) *cellRefiner = 4; /* Hybrid */ 265575d3a19aSMatthew G. Knepley else *cellRefiner = 2; /* Quadrilateral */ 265675d3a19aSMatthew G. Knepley break; 265775d3a19aSMatthew G. Knepley default: 265875d3a19aSMatthew G. Knepley SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 265975d3a19aSMatthew G. Knepley } 266075d3a19aSMatthew G. Knepley break; 2661*b5da9499SMatthew G. Knepley case 3: 2662*b5da9499SMatthew G. Knepley switch (coneSize) { 2663*b5da9499SMatthew G. Knepley case 4: 2664*b5da9499SMatthew G. Knepley if (cMax >= 0) *cellRefiner = 7; /* Hybrid */ 2665*b5da9499SMatthew G. Knepley else *cellRefiner = 5; /* Tetrahedral */ 2666*b5da9499SMatthew G. Knepley break; 2667*b5da9499SMatthew G. Knepley default: 2668*b5da9499SMatthew G. Knepley SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 2669*b5da9499SMatthew G. Knepley } 2670*b5da9499SMatthew G. Knepley break; 267175d3a19aSMatthew G. Knepley default: 267275d3a19aSMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 267375d3a19aSMatthew G. Knepley } 267475d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 267575d3a19aSMatthew G. Knepley } 2676