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