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