1*75d3a19aSMatthew G. Knepley #include <petsc-private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2*75d3a19aSMatthew G. Knepley #include <petscsf.h> 3*75d3a19aSMatthew G. Knepley 4*75d3a19aSMatthew G. Knepley #undef __FUNCT__ 5*75d3a19aSMatthew G. Knepley #define __FUNCT__ "GetDepthStart_Private" 6*75d3a19aSMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode GetDepthStart_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cStart, PetscInt *fStart, PetscInt *eStart, PetscInt *vStart) 7*75d3a19aSMatthew G. Knepley { 8*75d3a19aSMatthew G. Knepley PetscFunctionBegin; 9*75d3a19aSMatthew G. Knepley if (cStart) *cStart = 0; 10*75d3a19aSMatthew G. Knepley if (vStart) *vStart = depthSize[depth]; 11*75d3a19aSMatthew G. Knepley if (fStart) *fStart = depthSize[depth] + depthSize[0]; 12*75d3a19aSMatthew G. Knepley if (eStart) *eStart = depthSize[depth] + depthSize[0] + depthSize[depth-1]; 13*75d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 14*75d3a19aSMatthew G. Knepley } 15*75d3a19aSMatthew G. Knepley 16*75d3a19aSMatthew G. Knepley #undef __FUNCT__ 17*75d3a19aSMatthew G. Knepley #define __FUNCT__ "GetDepthEnd_Private" 18*75d3a19aSMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode GetDepthEnd_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cEnd, PetscInt *fEnd, PetscInt *eEnd, PetscInt *vEnd) 19*75d3a19aSMatthew G. Knepley { 20*75d3a19aSMatthew G. Knepley PetscFunctionBegin; 21*75d3a19aSMatthew G. Knepley if (cEnd) *cEnd = depthSize[depth]; 22*75d3a19aSMatthew G. Knepley if (vEnd) *vEnd = depthSize[depth] + depthSize[0]; 23*75d3a19aSMatthew G. Knepley if (fEnd) *fEnd = depthSize[depth] + depthSize[0] + depthSize[depth-1]; 24*75d3a19aSMatthew G. Knepley if (eEnd) *eEnd = depthSize[depth] + depthSize[0] + depthSize[depth-1] + depthSize[1]; 25*75d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 26*75d3a19aSMatthew G. Knepley } 27*75d3a19aSMatthew G. Knepley 28*75d3a19aSMatthew G. Knepley #undef __FUNCT__ 29*75d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerGetSizes" 30*75d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[]) 31*75d3a19aSMatthew G. Knepley { 32*75d3a19aSMatthew G. Knepley PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 33*75d3a19aSMatthew G. Knepley PetscErrorCode ierr; 34*75d3a19aSMatthew G. Knepley 35*75d3a19aSMatthew G. Knepley PetscFunctionBegin; 36*75d3a19aSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 37*75d3a19aSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 38*75d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 39*75d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 40*75d3a19aSMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 41*75d3a19aSMatthew G. Knepley switch (refiner) { 42*75d3a19aSMatthew G. Knepley case 1: 43*75d3a19aSMatthew G. Knepley /* Simplicial 2D */ 44*75d3a19aSMatthew G. Knepley depthSize[0] = vEnd - vStart + fEnd - fStart; /* Add a vertex on every face */ 45*75d3a19aSMatthew 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 */ 46*75d3a19aSMatthew G. Knepley depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 47*75d3a19aSMatthew G. Knepley break; 48*75d3a19aSMatthew G. Knepley case 3: 49*75d3a19aSMatthew G. Knepley /* Hybrid 2D */ 50*75d3a19aSMatthew G. Knepley if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 51*75d3a19aSMatthew G. Knepley cMax = PetscMin(cEnd, cMax); 52*75d3a19aSMatthew G. Knepley if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 53*75d3a19aSMatthew G. Knepley fMax = PetscMin(fEnd, fMax); 54*75d3a19aSMatthew G. Knepley depthSize[0] = vEnd - vStart + fMax - fStart; /* Add a vertex on every face, but not hybrid faces */ 55*75d3a19aSMatthew 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 */ 56*75d3a19aSMatthew G. Knepley depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax); /* Interior cells split into 4 cells, Hybrid cells split into 2 cells */ 57*75d3a19aSMatthew G. Knepley break; 58*75d3a19aSMatthew G. Knepley case 2: 59*75d3a19aSMatthew G. Knepley /* Hex 2D */ 60*75d3a19aSMatthew G. Knepley depthSize[0] = vEnd - vStart + cEnd - cStart + fEnd - fStart; /* Add a vertex on every face and cell */ 61*75d3a19aSMatthew 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 */ 62*75d3a19aSMatthew G. Knepley depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 63*75d3a19aSMatthew G. Knepley break; 64*75d3a19aSMatthew G. Knepley default: 65*75d3a19aSMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 66*75d3a19aSMatthew G. Knepley } 67*75d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 68*75d3a19aSMatthew G. Knepley } 69*75d3a19aSMatthew G. Knepley 70*75d3a19aSMatthew G. Knepley #undef __FUNCT__ 71*75d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetConeSizes" 72*75d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 73*75d3a19aSMatthew G. Knepley { 74*75d3a19aSMatthew G. Knepley PetscInt depth, cStart, cStartNew, cEnd, cMax, c, vStart, vStartNew, vEnd, vMax, v, fStart, fStartNew, fEnd, fMax, f, eStart, eStartNew, eEnd, eMax, r; 75*75d3a19aSMatthew G. Knepley PetscErrorCode ierr; 76*75d3a19aSMatthew G. Knepley 77*75d3a19aSMatthew G. Knepley PetscFunctionBegin; 78*75d3a19aSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 79*75d3a19aSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 80*75d3a19aSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 81*75d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 82*75d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 83*75d3a19aSMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 84*75d3a19aSMatthew G. Knepley ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 85*75d3a19aSMatthew G. Knepley switch (refiner) { 86*75d3a19aSMatthew G. Knepley case 1: 87*75d3a19aSMatthew G. Knepley /* Simplicial 2D */ 88*75d3a19aSMatthew G. Knepley /* All cells have 3 faces */ 89*75d3a19aSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 90*75d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r) { 91*75d3a19aSMatthew G. Knepley const PetscInt newp = (c - cStart)*4 + r; 92*75d3a19aSMatthew G. Knepley 93*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 94*75d3a19aSMatthew G. Knepley } 95*75d3a19aSMatthew G. Knepley } 96*75d3a19aSMatthew G. Knepley /* Split faces have 2 vertices and the same cells as the parent */ 97*75d3a19aSMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 98*75d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 99*75d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (f - fStart)*2 + r; 100*75d3a19aSMatthew G. Knepley PetscInt size; 101*75d3a19aSMatthew G. Knepley 102*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 103*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 104*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 105*75d3a19aSMatthew G. Knepley } 106*75d3a19aSMatthew G. Knepley } 107*75d3a19aSMatthew G. Knepley /* Interior faces have 2 vertices and 2 cells */ 108*75d3a19aSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 109*75d3a19aSMatthew G. Knepley for (r = 0; r < 3; ++r) { 110*75d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 111*75d3a19aSMatthew G. Knepley 112*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 113*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 114*75d3a19aSMatthew G. Knepley } 115*75d3a19aSMatthew G. Knepley } 116*75d3a19aSMatthew G. Knepley /* Old vertices have identical supports */ 117*75d3a19aSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 118*75d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (v - vStart); 119*75d3a19aSMatthew G. Knepley PetscInt size; 120*75d3a19aSMatthew G. Knepley 121*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 122*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 123*75d3a19aSMatthew G. Knepley } 124*75d3a19aSMatthew G. Knepley /* Face vertices have 2 + cells*2 supports */ 125*75d3a19aSMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 126*75d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 127*75d3a19aSMatthew G. Knepley PetscInt size; 128*75d3a19aSMatthew G. Knepley 129*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 130*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr); 131*75d3a19aSMatthew G. Knepley } 132*75d3a19aSMatthew G. Knepley break; 133*75d3a19aSMatthew G. Knepley case 2: 134*75d3a19aSMatthew G. Knepley /* Hex 2D */ 135*75d3a19aSMatthew G. Knepley /* All cells have 4 faces */ 136*75d3a19aSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 137*75d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r) { 138*75d3a19aSMatthew G. Knepley const PetscInt newp = (c - cStart)*4 + r; 139*75d3a19aSMatthew G. Knepley 140*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 141*75d3a19aSMatthew G. Knepley } 142*75d3a19aSMatthew G. Knepley } 143*75d3a19aSMatthew G. Knepley /* Split faces have 2 vertices and the same cells as the parent */ 144*75d3a19aSMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 145*75d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 146*75d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (f - fStart)*2 + r; 147*75d3a19aSMatthew G. Knepley PetscInt size; 148*75d3a19aSMatthew G. Knepley 149*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 150*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 151*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 152*75d3a19aSMatthew G. Knepley } 153*75d3a19aSMatthew G. Knepley } 154*75d3a19aSMatthew G. Knepley /* Interior faces have 2 vertices and 2 cells */ 155*75d3a19aSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 156*75d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r) { 157*75d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 158*75d3a19aSMatthew G. Knepley 159*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 160*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 161*75d3a19aSMatthew G. Knepley } 162*75d3a19aSMatthew G. Knepley } 163*75d3a19aSMatthew G. Knepley /* Old vertices have identical supports */ 164*75d3a19aSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 165*75d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (v - vStart); 166*75d3a19aSMatthew G. Knepley PetscInt size; 167*75d3a19aSMatthew G. Knepley 168*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 169*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 170*75d3a19aSMatthew G. Knepley } 171*75d3a19aSMatthew G. Knepley /* Face vertices have 2 + cells supports */ 172*75d3a19aSMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 173*75d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 174*75d3a19aSMatthew G. Knepley PetscInt size; 175*75d3a19aSMatthew G. Knepley 176*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 177*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 178*75d3a19aSMatthew G. Knepley } 179*75d3a19aSMatthew G. Knepley /* Cell vertices have 4 supports */ 180*75d3a19aSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 181*75d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 182*75d3a19aSMatthew G. Knepley 183*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 184*75d3a19aSMatthew G. Knepley } 185*75d3a19aSMatthew G. Knepley break; 186*75d3a19aSMatthew G. Knepley case 3: 187*75d3a19aSMatthew G. Knepley /* Hybrid 2D */ 188*75d3a19aSMatthew G. Knepley if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 189*75d3a19aSMatthew G. Knepley cMax = PetscMin(cEnd, cMax); 190*75d3a19aSMatthew G. Knepley if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 191*75d3a19aSMatthew G. Knepley fMax = PetscMin(fEnd, fMax); 192*75d3a19aSMatthew G. Knepley ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 193*75d3a19aSMatthew G. Knepley /* Interior cells have 3 faces */ 194*75d3a19aSMatthew G. Knepley for (c = cStart; c < cMax; ++c) { 195*75d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r) { 196*75d3a19aSMatthew G. Knepley const PetscInt newp = cStartNew + (c - cStart)*4 + r; 197*75d3a19aSMatthew G. Knepley 198*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 199*75d3a19aSMatthew G. Knepley } 200*75d3a19aSMatthew G. Knepley } 201*75d3a19aSMatthew G. Knepley /* Hybrid cells have 4 faces */ 202*75d3a19aSMatthew G. Knepley for (c = cMax; c < cEnd; ++c) { 203*75d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 204*75d3a19aSMatthew G. Knepley const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 205*75d3a19aSMatthew G. Knepley 206*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 207*75d3a19aSMatthew G. Knepley } 208*75d3a19aSMatthew G. Knepley } 209*75d3a19aSMatthew G. Knepley /* Interior split faces have 2 vertices and the same cells as the parent */ 210*75d3a19aSMatthew G. Knepley for (f = fStart; f < fMax; ++f) { 211*75d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 212*75d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (f - fStart)*2 + r; 213*75d3a19aSMatthew G. Knepley PetscInt size; 214*75d3a19aSMatthew G. Knepley 215*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 216*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 217*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 218*75d3a19aSMatthew G. Knepley } 219*75d3a19aSMatthew G. Knepley } 220*75d3a19aSMatthew G. Knepley /* Interior cell faces have 2 vertices and 2 cells */ 221*75d3a19aSMatthew G. Knepley for (c = cStart; c < cMax; ++c) { 222*75d3a19aSMatthew G. Knepley for (r = 0; r < 3; ++r) { 223*75d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 224*75d3a19aSMatthew G. Knepley 225*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 226*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 227*75d3a19aSMatthew G. Knepley } 228*75d3a19aSMatthew G. Knepley } 229*75d3a19aSMatthew G. Knepley /* Hybrid faces have 2 vertices and the same cells */ 230*75d3a19aSMatthew G. Knepley for (f = fMax; f < fEnd; ++f) { 231*75d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 232*75d3a19aSMatthew G. Knepley PetscInt size; 233*75d3a19aSMatthew G. Knepley 234*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 235*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 236*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 237*75d3a19aSMatthew G. Knepley } 238*75d3a19aSMatthew G. Knepley /* Hybrid cell faces have 2 vertices and 2 cells */ 239*75d3a19aSMatthew G. Knepley for (c = cMax; c < cEnd; ++c) { 240*75d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 241*75d3a19aSMatthew G. Knepley 242*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 243*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 244*75d3a19aSMatthew G. Knepley } 245*75d3a19aSMatthew G. Knepley /* Old vertices have identical supports */ 246*75d3a19aSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 247*75d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (v - vStart); 248*75d3a19aSMatthew G. Knepley PetscInt size; 249*75d3a19aSMatthew G. Knepley 250*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 251*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 252*75d3a19aSMatthew G. Knepley } 253*75d3a19aSMatthew G. Knepley /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 254*75d3a19aSMatthew G. Knepley for (f = fStart; f < fMax; ++f) { 255*75d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 256*75d3a19aSMatthew G. Knepley const PetscInt *support; 257*75d3a19aSMatthew G. Knepley PetscInt size, newSize = 2, s; 258*75d3a19aSMatthew G. Knepley 259*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 260*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 261*75d3a19aSMatthew G. Knepley for (s = 0; s < size; ++s) { 262*75d3a19aSMatthew G. Knepley if (support[s] >= cMax) newSize += 1; 263*75d3a19aSMatthew G. Knepley else newSize += 2; 264*75d3a19aSMatthew G. Knepley } 265*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr); 266*75d3a19aSMatthew G. Knepley } 267*75d3a19aSMatthew G. Knepley break; 268*75d3a19aSMatthew G. Knepley default: 269*75d3a19aSMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 270*75d3a19aSMatthew G. Knepley } 271*75d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 272*75d3a19aSMatthew G. Knepley } 273*75d3a19aSMatthew G. Knepley 274*75d3a19aSMatthew G. Knepley #undef __FUNCT__ 275*75d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCones" 276*75d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 277*75d3a19aSMatthew G. Knepley { 278*75d3a19aSMatthew 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; 279*75d3a19aSMatthew G. Knepley PetscInt maxSupportSize, *supportRef; 280*75d3a19aSMatthew G. Knepley PetscErrorCode ierr; 281*75d3a19aSMatthew G. Knepley 282*75d3a19aSMatthew G. Knepley PetscFunctionBegin; 283*75d3a19aSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 284*75d3a19aSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 285*75d3a19aSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 286*75d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 287*75d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 288*75d3a19aSMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 289*75d3a19aSMatthew G. Knepley ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 290*75d3a19aSMatthew G. Knepley ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 291*75d3a19aSMatthew G. Knepley switch (refiner) { 292*75d3a19aSMatthew G. Knepley case 1: 293*75d3a19aSMatthew G. Knepley /* Simplicial 2D */ 294*75d3a19aSMatthew G. Knepley /* 295*75d3a19aSMatthew G. Knepley 2 296*75d3a19aSMatthew G. Knepley |\ 297*75d3a19aSMatthew G. Knepley | \ 298*75d3a19aSMatthew G. Knepley | \ 299*75d3a19aSMatthew G. Knepley | \ 300*75d3a19aSMatthew G. Knepley | C \ 301*75d3a19aSMatthew G. Knepley | \ 302*75d3a19aSMatthew G. Knepley | \ 303*75d3a19aSMatthew G. Knepley 2---1---1 304*75d3a19aSMatthew G. Knepley |\ D / \ 305*75d3a19aSMatthew G. Knepley | 2 0 \ 306*75d3a19aSMatthew G. Knepley |A \ / B \ 307*75d3a19aSMatthew G. Knepley 0---0-------1 308*75d3a19aSMatthew G. Knepley */ 309*75d3a19aSMatthew G. Knepley /* All cells have 3 faces */ 310*75d3a19aSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 311*75d3a19aSMatthew G. Knepley const PetscInt newp = cStartNew + (c - cStart)*4; 312*75d3a19aSMatthew G. Knepley const PetscInt *cone, *ornt; 313*75d3a19aSMatthew G. Knepley PetscInt coneNew[3], orntNew[3]; 314*75d3a19aSMatthew G. Knepley 315*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 316*75d3a19aSMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 317*75d3a19aSMatthew G. Knepley /* A triangle */ 318*75d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 319*75d3a19aSMatthew G. Knepley orntNew[0] = ornt[0]; 320*75d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 321*75d3a19aSMatthew G. Knepley orntNew[1] = -2; 322*75d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 323*75d3a19aSMatthew G. Knepley orntNew[2] = ornt[2]; 324*75d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 325*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 326*75d3a19aSMatthew G. Knepley #if 1 327*75d3a19aSMatthew 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); 328*75d3a19aSMatthew G. Knepley for (p = 0; p < 3; ++p) { 329*75d3a19aSMatthew 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); 330*75d3a19aSMatthew G. Knepley } 331*75d3a19aSMatthew G. Knepley #endif 332*75d3a19aSMatthew G. Knepley /* B triangle */ 333*75d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 334*75d3a19aSMatthew G. Knepley orntNew[0] = ornt[0]; 335*75d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 336*75d3a19aSMatthew G. Knepley orntNew[1] = ornt[1]; 337*75d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 338*75d3a19aSMatthew G. Knepley orntNew[2] = -2; 339*75d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 340*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 341*75d3a19aSMatthew G. Knepley #if 1 342*75d3a19aSMatthew 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); 343*75d3a19aSMatthew G. Knepley for (p = 0; p < 3; ++p) { 344*75d3a19aSMatthew 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); 345*75d3a19aSMatthew G. Knepley } 346*75d3a19aSMatthew G. Knepley #endif 347*75d3a19aSMatthew G. Knepley /* C triangle */ 348*75d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 349*75d3a19aSMatthew G. Knepley orntNew[0] = -2; 350*75d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 351*75d3a19aSMatthew G. Knepley orntNew[1] = ornt[1]; 352*75d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 353*75d3a19aSMatthew G. Knepley orntNew[2] = ornt[2]; 354*75d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 355*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 356*75d3a19aSMatthew G. Knepley #if 1 357*75d3a19aSMatthew 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); 358*75d3a19aSMatthew G. Knepley for (p = 0; p < 3; ++p) { 359*75d3a19aSMatthew 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); 360*75d3a19aSMatthew G. Knepley } 361*75d3a19aSMatthew G. Knepley #endif 362*75d3a19aSMatthew G. Knepley /* D triangle */ 363*75d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 364*75d3a19aSMatthew G. Knepley orntNew[0] = 0; 365*75d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 366*75d3a19aSMatthew G. Knepley orntNew[1] = 0; 367*75d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 368*75d3a19aSMatthew G. Knepley orntNew[2] = 0; 369*75d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 370*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 371*75d3a19aSMatthew G. Knepley #if 1 372*75d3a19aSMatthew 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); 373*75d3a19aSMatthew G. Knepley for (p = 0; p < 3; ++p) { 374*75d3a19aSMatthew 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); 375*75d3a19aSMatthew G. Knepley } 376*75d3a19aSMatthew G. Knepley #endif 377*75d3a19aSMatthew G. Knepley } 378*75d3a19aSMatthew G. Knepley /* Split faces have 2 vertices and the same cells as the parent */ 379*75d3a19aSMatthew G. Knepley ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 380*75d3a19aSMatthew G. Knepley ierr = PetscMalloc((2 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr); 381*75d3a19aSMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 382*75d3a19aSMatthew G. Knepley const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 383*75d3a19aSMatthew G. Knepley 384*75d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 385*75d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (f - fStart)*2 + r; 386*75d3a19aSMatthew G. Knepley const PetscInt *cone, *support; 387*75d3a19aSMatthew G. Knepley PetscInt coneNew[2], coneSize, c, supportSize, s; 388*75d3a19aSMatthew G. Knepley 389*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 390*75d3a19aSMatthew G. Knepley coneNew[0] = vStartNew + (cone[0] - vStart); 391*75d3a19aSMatthew G. Knepley coneNew[1] = vStartNew + (cone[1] - vStart); 392*75d3a19aSMatthew G. Knepley coneNew[(r+1)%2] = newv; 393*75d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 394*75d3a19aSMatthew G. Knepley #if 1 395*75d3a19aSMatthew 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); 396*75d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 397*75d3a19aSMatthew 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); 398*75d3a19aSMatthew G. Knepley } 399*75d3a19aSMatthew G. Knepley #endif 400*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 401*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 402*75d3a19aSMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 403*75d3a19aSMatthew G. Knepley ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 404*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 405*75d3a19aSMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 406*75d3a19aSMatthew G. Knepley if (cone[c] == f) break; 407*75d3a19aSMatthew G. Knepley } 408*75d3a19aSMatthew G. Knepley supportRef[s] = cStartNew + (support[s] - cStart)*4 + (c+r)%3; 409*75d3a19aSMatthew G. Knepley } 410*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 411*75d3a19aSMatthew G. Knepley #if 1 412*75d3a19aSMatthew 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); 413*75d3a19aSMatthew G. Knepley for (p = 0; p < supportSize; ++p) { 414*75d3a19aSMatthew 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); 415*75d3a19aSMatthew G. Knepley } 416*75d3a19aSMatthew G. Knepley #endif 417*75d3a19aSMatthew G. Knepley } 418*75d3a19aSMatthew G. Knepley } 419*75d3a19aSMatthew G. Knepley /* Interior faces have 2 vertices and 2 cells */ 420*75d3a19aSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 421*75d3a19aSMatthew G. Knepley const PetscInt *cone; 422*75d3a19aSMatthew G. Knepley 423*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 424*75d3a19aSMatthew G. Knepley for (r = 0; r < 3; ++r) { 425*75d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 426*75d3a19aSMatthew G. Knepley PetscInt coneNew[2]; 427*75d3a19aSMatthew G. Knepley PetscInt supportNew[2]; 428*75d3a19aSMatthew G. Knepley 429*75d3a19aSMatthew G. Knepley coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 430*75d3a19aSMatthew G. Knepley coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 431*75d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 432*75d3a19aSMatthew G. Knepley #if 1 433*75d3a19aSMatthew 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); 434*75d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 435*75d3a19aSMatthew 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); 436*75d3a19aSMatthew G. Knepley } 437*75d3a19aSMatthew G. Knepley #endif 438*75d3a19aSMatthew G. Knepley supportNew[0] = (c - cStart)*4 + (r+1)%3; 439*75d3a19aSMatthew G. Knepley supportNew[1] = (c - cStart)*4 + 3; 440*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 441*75d3a19aSMatthew G. Knepley #if 1 442*75d3a19aSMatthew 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); 443*75d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 444*75d3a19aSMatthew 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); 445*75d3a19aSMatthew G. Knepley } 446*75d3a19aSMatthew G. Knepley #endif 447*75d3a19aSMatthew G. Knepley } 448*75d3a19aSMatthew G. Knepley } 449*75d3a19aSMatthew G. Knepley /* Old vertices have identical supports */ 450*75d3a19aSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 451*75d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (v - vStart); 452*75d3a19aSMatthew G. Knepley const PetscInt *support, *cone; 453*75d3a19aSMatthew G. Knepley PetscInt size, s; 454*75d3a19aSMatthew G. Knepley 455*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 456*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 457*75d3a19aSMatthew G. Knepley for (s = 0; s < size; ++s) { 458*75d3a19aSMatthew G. Knepley PetscInt r = 0; 459*75d3a19aSMatthew G. Knepley 460*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 461*75d3a19aSMatthew G. Knepley if (cone[1] == v) r = 1; 462*75d3a19aSMatthew G. Knepley supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 463*75d3a19aSMatthew G. Knepley } 464*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 465*75d3a19aSMatthew G. Knepley #if 1 466*75d3a19aSMatthew 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); 467*75d3a19aSMatthew G. Knepley for (p = 0; p < size; ++p) { 468*75d3a19aSMatthew 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); 469*75d3a19aSMatthew G. Knepley } 470*75d3a19aSMatthew G. Knepley #endif 471*75d3a19aSMatthew G. Knepley } 472*75d3a19aSMatthew G. Knepley /* Face vertices have 2 + cells*2 supports */ 473*75d3a19aSMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 474*75d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 475*75d3a19aSMatthew G. Knepley const PetscInt *cone, *support; 476*75d3a19aSMatthew G. Knepley PetscInt size, s; 477*75d3a19aSMatthew G. Knepley 478*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 479*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 480*75d3a19aSMatthew G. Knepley supportRef[0] = fStartNew + (f - fStart)*2 + 0; 481*75d3a19aSMatthew G. Knepley supportRef[1] = fStartNew + (f - fStart)*2 + 1; 482*75d3a19aSMatthew G. Knepley for (s = 0; s < size; ++s) { 483*75d3a19aSMatthew G. Knepley PetscInt r = 0; 484*75d3a19aSMatthew G. Knepley 485*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 486*75d3a19aSMatthew G. Knepley if (cone[1] == f) r = 1; 487*75d3a19aSMatthew G. Knepley else if (cone[2] == f) r = 2; 488*75d3a19aSMatthew G. Knepley supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 489*75d3a19aSMatthew G. Knepley supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 490*75d3a19aSMatthew G. Knepley } 491*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 492*75d3a19aSMatthew G. Knepley #if 1 493*75d3a19aSMatthew 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); 494*75d3a19aSMatthew G. Knepley for (p = 0; p < 2+size*2; ++p) { 495*75d3a19aSMatthew 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); 496*75d3a19aSMatthew G. Knepley } 497*75d3a19aSMatthew G. Knepley #endif 498*75d3a19aSMatthew G. Knepley } 499*75d3a19aSMatthew G. Knepley ierr = PetscFree(supportRef);CHKERRQ(ierr); 500*75d3a19aSMatthew G. Knepley break; 501*75d3a19aSMatthew G. Knepley case 2: 502*75d3a19aSMatthew G. Knepley /* Hex 2D */ 503*75d3a19aSMatthew G. Knepley /* 504*75d3a19aSMatthew G. Knepley 3---------2---------2 505*75d3a19aSMatthew G. Knepley | | | 506*75d3a19aSMatthew G. Knepley | D 2 C | 507*75d3a19aSMatthew G. Knepley | | | 508*75d3a19aSMatthew G. Knepley 3----3----0----1----1 509*75d3a19aSMatthew G. Knepley | | | 510*75d3a19aSMatthew G. Knepley | A 0 B | 511*75d3a19aSMatthew G. Knepley | | | 512*75d3a19aSMatthew G. Knepley 0---------0---------1 513*75d3a19aSMatthew G. Knepley */ 514*75d3a19aSMatthew G. Knepley /* All cells have 4 faces */ 515*75d3a19aSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 516*75d3a19aSMatthew G. Knepley const PetscInt newp = (c - cStart)*4; 517*75d3a19aSMatthew G. Knepley const PetscInt *cone, *ornt; 518*75d3a19aSMatthew G. Knepley PetscInt coneNew[4], orntNew[4]; 519*75d3a19aSMatthew G. Knepley 520*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 521*75d3a19aSMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 522*75d3a19aSMatthew G. Knepley /* A quad */ 523*75d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 524*75d3a19aSMatthew G. Knepley orntNew[0] = ornt[0]; 525*75d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 526*75d3a19aSMatthew G. Knepley orntNew[1] = 0; 527*75d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 528*75d3a19aSMatthew G. Knepley orntNew[2] = -2; 529*75d3a19aSMatthew G. Knepley coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 530*75d3a19aSMatthew G. Knepley orntNew[3] = ornt[3]; 531*75d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 532*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 533*75d3a19aSMatthew G. Knepley #if 1 534*75d3a19aSMatthew 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); 535*75d3a19aSMatthew G. Knepley for (p = 0; p < 4; ++p) { 536*75d3a19aSMatthew 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); 537*75d3a19aSMatthew G. Knepley } 538*75d3a19aSMatthew G. Knepley #endif 539*75d3a19aSMatthew G. Knepley /* B quad */ 540*75d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 541*75d3a19aSMatthew G. Knepley orntNew[0] = ornt[0]; 542*75d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 543*75d3a19aSMatthew G. Knepley orntNew[1] = ornt[1]; 544*75d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 545*75d3a19aSMatthew G. Knepley orntNew[2] = 0; 546*75d3a19aSMatthew G. Knepley coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 547*75d3a19aSMatthew G. Knepley orntNew[3] = -2; 548*75d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 549*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 550*75d3a19aSMatthew G. Knepley #if 1 551*75d3a19aSMatthew 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); 552*75d3a19aSMatthew G. Knepley for (p = 0; p < 4; ++p) { 553*75d3a19aSMatthew 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); 554*75d3a19aSMatthew G. Knepley } 555*75d3a19aSMatthew G. Knepley #endif 556*75d3a19aSMatthew G. Knepley /* C quad */ 557*75d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 558*75d3a19aSMatthew G. Knepley orntNew[0] = -2; 559*75d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 560*75d3a19aSMatthew G. Knepley orntNew[1] = ornt[1]; 561*75d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 562*75d3a19aSMatthew G. Knepley orntNew[2] = ornt[2]; 563*75d3a19aSMatthew G. Knepley coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 564*75d3a19aSMatthew G. Knepley orntNew[3] = 0; 565*75d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 566*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 567*75d3a19aSMatthew G. Knepley #if 1 568*75d3a19aSMatthew 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); 569*75d3a19aSMatthew G. Knepley for (p = 0; p < 4; ++p) { 570*75d3a19aSMatthew 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); 571*75d3a19aSMatthew G. Knepley } 572*75d3a19aSMatthew G. Knepley #endif 573*75d3a19aSMatthew G. Knepley /* D quad */ 574*75d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 575*75d3a19aSMatthew G. Knepley orntNew[0] = 0; 576*75d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 577*75d3a19aSMatthew G. Knepley orntNew[1] = -2; 578*75d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 579*75d3a19aSMatthew G. Knepley orntNew[2] = ornt[2]; 580*75d3a19aSMatthew G. Knepley coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 581*75d3a19aSMatthew G. Knepley orntNew[3] = ornt[3]; 582*75d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 583*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 584*75d3a19aSMatthew G. Knepley #if 1 585*75d3a19aSMatthew 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); 586*75d3a19aSMatthew G. Knepley for (p = 0; p < 4; ++p) { 587*75d3a19aSMatthew 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); 588*75d3a19aSMatthew G. Knepley } 589*75d3a19aSMatthew G. Knepley #endif 590*75d3a19aSMatthew G. Knepley } 591*75d3a19aSMatthew G. Knepley /* Split faces have 2 vertices and the same cells as the parent */ 592*75d3a19aSMatthew G. Knepley ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 593*75d3a19aSMatthew G. Knepley ierr = PetscMalloc((2 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr); 594*75d3a19aSMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 595*75d3a19aSMatthew G. Knepley const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 596*75d3a19aSMatthew G. Knepley 597*75d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 598*75d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (f - fStart)*2 + r; 599*75d3a19aSMatthew G. Knepley const PetscInt *cone, *support; 600*75d3a19aSMatthew G. Knepley PetscInt coneNew[2], coneSize, c, supportSize, s; 601*75d3a19aSMatthew G. Knepley 602*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 603*75d3a19aSMatthew G. Knepley coneNew[0] = vStartNew + (cone[0] - vStart); 604*75d3a19aSMatthew G. Knepley coneNew[1] = vStartNew + (cone[1] - vStart); 605*75d3a19aSMatthew G. Knepley coneNew[(r+1)%2] = newv; 606*75d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 607*75d3a19aSMatthew G. Knepley #if 1 608*75d3a19aSMatthew 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); 609*75d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 610*75d3a19aSMatthew 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); 611*75d3a19aSMatthew G. Knepley } 612*75d3a19aSMatthew G. Knepley #endif 613*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 614*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 615*75d3a19aSMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 616*75d3a19aSMatthew G. Knepley ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 617*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 618*75d3a19aSMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 619*75d3a19aSMatthew G. Knepley if (cone[c] == f) break; 620*75d3a19aSMatthew G. Knepley } 621*75d3a19aSMatthew G. Knepley supportRef[s] = cStartNew + (support[s] - cStart)*4 + (c+r)%4; 622*75d3a19aSMatthew G. Knepley } 623*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 624*75d3a19aSMatthew G. Knepley #if 1 625*75d3a19aSMatthew 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); 626*75d3a19aSMatthew G. Knepley for (p = 0; p < supportSize; ++p) { 627*75d3a19aSMatthew 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); 628*75d3a19aSMatthew G. Knepley } 629*75d3a19aSMatthew G. Knepley #endif 630*75d3a19aSMatthew G. Knepley } 631*75d3a19aSMatthew G. Knepley } 632*75d3a19aSMatthew G. Knepley /* Interior faces have 2 vertices and 2 cells */ 633*75d3a19aSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 634*75d3a19aSMatthew G. Knepley const PetscInt *cone; 635*75d3a19aSMatthew G. Knepley PetscInt coneNew[2], supportNew[2]; 636*75d3a19aSMatthew G. Knepley 637*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 638*75d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r) { 639*75d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 640*75d3a19aSMatthew G. Knepley 641*75d3a19aSMatthew G. Knepley coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 642*75d3a19aSMatthew G. Knepley coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 643*75d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 644*75d3a19aSMatthew G. Knepley #if 1 645*75d3a19aSMatthew 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); 646*75d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 647*75d3a19aSMatthew 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); 648*75d3a19aSMatthew G. Knepley } 649*75d3a19aSMatthew G. Knepley #endif 650*75d3a19aSMatthew G. Knepley supportNew[0] = (c - cStart)*4 + r; 651*75d3a19aSMatthew G. Knepley supportNew[1] = (c - cStart)*4 + (r+1)%4; 652*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 653*75d3a19aSMatthew G. Knepley #if 1 654*75d3a19aSMatthew 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); 655*75d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 656*75d3a19aSMatthew 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); 657*75d3a19aSMatthew G. Knepley } 658*75d3a19aSMatthew G. Knepley #endif 659*75d3a19aSMatthew G. Knepley } 660*75d3a19aSMatthew G. Knepley } 661*75d3a19aSMatthew G. Knepley /* Old vertices have identical supports */ 662*75d3a19aSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 663*75d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (v - vStart); 664*75d3a19aSMatthew G. Knepley const PetscInt *support, *cone; 665*75d3a19aSMatthew G. Knepley PetscInt size, s; 666*75d3a19aSMatthew G. Knepley 667*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 668*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 669*75d3a19aSMatthew G. Knepley for (s = 0; s < size; ++s) { 670*75d3a19aSMatthew G. Knepley PetscInt r = 0; 671*75d3a19aSMatthew G. Knepley 672*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 673*75d3a19aSMatthew G. Knepley if (cone[1] == v) r = 1; 674*75d3a19aSMatthew G. Knepley supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 675*75d3a19aSMatthew G. Knepley } 676*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 677*75d3a19aSMatthew G. Knepley #if 1 678*75d3a19aSMatthew 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); 679*75d3a19aSMatthew G. Knepley for (p = 0; p < size; ++p) { 680*75d3a19aSMatthew 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); 681*75d3a19aSMatthew G. Knepley } 682*75d3a19aSMatthew G. Knepley #endif 683*75d3a19aSMatthew G. Knepley } 684*75d3a19aSMatthew G. Knepley /* Face vertices have 2 + cells supports */ 685*75d3a19aSMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 686*75d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 687*75d3a19aSMatthew G. Knepley const PetscInt *cone, *support; 688*75d3a19aSMatthew G. Knepley PetscInt size, s; 689*75d3a19aSMatthew G. Knepley 690*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 691*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 692*75d3a19aSMatthew G. Knepley supportRef[0] = fStartNew + (f - fStart)*2 + 0; 693*75d3a19aSMatthew G. Knepley supportRef[1] = fStartNew + (f - fStart)*2 + 1; 694*75d3a19aSMatthew G. Knepley for (s = 0; s < size; ++s) { 695*75d3a19aSMatthew G. Knepley PetscInt r = 0; 696*75d3a19aSMatthew G. Knepley 697*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 698*75d3a19aSMatthew G. Knepley if (cone[1] == f) r = 1; 699*75d3a19aSMatthew G. Knepley else if (cone[2] == f) r = 2; 700*75d3a19aSMatthew G. Knepley else if (cone[3] == f) r = 3; 701*75d3a19aSMatthew G. Knepley supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r; 702*75d3a19aSMatthew G. Knepley } 703*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 704*75d3a19aSMatthew G. Knepley #if 1 705*75d3a19aSMatthew 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); 706*75d3a19aSMatthew G. Knepley for (p = 0; p < 2+size; ++p) { 707*75d3a19aSMatthew 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); 708*75d3a19aSMatthew G. Knepley } 709*75d3a19aSMatthew G. Knepley #endif 710*75d3a19aSMatthew G. Knepley } 711*75d3a19aSMatthew G. Knepley /* Cell vertices have 4 supports */ 712*75d3a19aSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 713*75d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 714*75d3a19aSMatthew G. Knepley PetscInt supportNew[4]; 715*75d3a19aSMatthew G. Knepley 716*75d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r) { 717*75d3a19aSMatthew G. Knepley supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 718*75d3a19aSMatthew G. Knepley } 719*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 720*75d3a19aSMatthew G. Knepley } 721*75d3a19aSMatthew G. Knepley break; 722*75d3a19aSMatthew G. Knepley case 3: 723*75d3a19aSMatthew G. Knepley if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 724*75d3a19aSMatthew G. Knepley cMax = PetscMin(cEnd, cMax); 725*75d3a19aSMatthew G. Knepley if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 726*75d3a19aSMatthew G. Knepley fMax = PetscMin(fEnd, fMax); 727*75d3a19aSMatthew G. Knepley /* Interior cells have 3 faces */ 728*75d3a19aSMatthew G. Knepley for (c = cStart; c < cMax; ++c) { 729*75d3a19aSMatthew G. Knepley const PetscInt newp = cStartNew + (c - cStart)*4; 730*75d3a19aSMatthew G. Knepley const PetscInt *cone, *ornt; 731*75d3a19aSMatthew G. Knepley PetscInt coneNew[3], orntNew[3]; 732*75d3a19aSMatthew G. Knepley 733*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 734*75d3a19aSMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 735*75d3a19aSMatthew G. Knepley /* A triangle */ 736*75d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 737*75d3a19aSMatthew G. Knepley orntNew[0] = ornt[0]; 738*75d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 739*75d3a19aSMatthew G. Knepley orntNew[1] = -2; 740*75d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 741*75d3a19aSMatthew G. Knepley orntNew[2] = ornt[2]; 742*75d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 743*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 744*75d3a19aSMatthew G. Knepley #if 1 745*75d3a19aSMatthew 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); 746*75d3a19aSMatthew G. Knepley for (p = 0; p < 3; ++p) { 747*75d3a19aSMatthew 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); 748*75d3a19aSMatthew G. Knepley } 749*75d3a19aSMatthew G. Knepley #endif 750*75d3a19aSMatthew G. Knepley /* B triangle */ 751*75d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 752*75d3a19aSMatthew G. Knepley orntNew[0] = ornt[0]; 753*75d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 754*75d3a19aSMatthew G. Knepley orntNew[1] = ornt[1]; 755*75d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 756*75d3a19aSMatthew G. Knepley orntNew[2] = -2; 757*75d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 758*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 759*75d3a19aSMatthew G. Knepley #if 1 760*75d3a19aSMatthew 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); 761*75d3a19aSMatthew G. Knepley for (p = 0; p < 3; ++p) { 762*75d3a19aSMatthew 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); 763*75d3a19aSMatthew G. Knepley } 764*75d3a19aSMatthew G. Knepley #endif 765*75d3a19aSMatthew G. Knepley /* C triangle */ 766*75d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 767*75d3a19aSMatthew G. Knepley orntNew[0] = -2; 768*75d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 769*75d3a19aSMatthew G. Knepley orntNew[1] = ornt[1]; 770*75d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 771*75d3a19aSMatthew G. Knepley orntNew[2] = ornt[2]; 772*75d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 773*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 774*75d3a19aSMatthew G. Knepley #if 1 775*75d3a19aSMatthew 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); 776*75d3a19aSMatthew G. Knepley for (p = 0; p < 3; ++p) { 777*75d3a19aSMatthew 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); 778*75d3a19aSMatthew G. Knepley } 779*75d3a19aSMatthew G. Knepley #endif 780*75d3a19aSMatthew G. Knepley /* D triangle */ 781*75d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 782*75d3a19aSMatthew G. Knepley orntNew[0] = 0; 783*75d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 784*75d3a19aSMatthew G. Knepley orntNew[1] = 0; 785*75d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 786*75d3a19aSMatthew G. Knepley orntNew[2] = 0; 787*75d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 788*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 789*75d3a19aSMatthew G. Knepley #if 1 790*75d3a19aSMatthew 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); 791*75d3a19aSMatthew G. Knepley for (p = 0; p < 3; ++p) { 792*75d3a19aSMatthew 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); 793*75d3a19aSMatthew G. Knepley } 794*75d3a19aSMatthew G. Knepley #endif 795*75d3a19aSMatthew G. Knepley } 796*75d3a19aSMatthew G. Knepley /* 797*75d3a19aSMatthew G. Knepley 2----3----3 798*75d3a19aSMatthew G. Knepley | | 799*75d3a19aSMatthew G. Knepley | B | 800*75d3a19aSMatthew G. Knepley | | 801*75d3a19aSMatthew G. Knepley 0----4--- 1 802*75d3a19aSMatthew G. Knepley | | 803*75d3a19aSMatthew G. Knepley | A | 804*75d3a19aSMatthew G. Knepley | | 805*75d3a19aSMatthew G. Knepley 0----2----1 806*75d3a19aSMatthew G. Knepley */ 807*75d3a19aSMatthew G. Knepley /* Hybrid cells have 4 faces */ 808*75d3a19aSMatthew G. Knepley for (c = cMax; c < cEnd; ++c) { 809*75d3a19aSMatthew G. Knepley const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 810*75d3a19aSMatthew G. Knepley const PetscInt *cone, *ornt; 811*75d3a19aSMatthew G. Knepley PetscInt coneNew[4], orntNew[4]; 812*75d3a19aSMatthew G. Knepley 813*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 814*75d3a19aSMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 815*75d3a19aSMatthew G. Knepley /* A quad */ 816*75d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 817*75d3a19aSMatthew G. Knepley orntNew[0] = ornt[0]; 818*75d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 819*75d3a19aSMatthew G. Knepley orntNew[1] = ornt[1]; 820*75d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2] - fMax); 821*75d3a19aSMatthew G. Knepley orntNew[2] = 0; 822*75d3a19aSMatthew G. Knepley coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 823*75d3a19aSMatthew G. Knepley orntNew[3] = 0; 824*75d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 825*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 826*75d3a19aSMatthew G. Knepley #if 1 827*75d3a19aSMatthew 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); 828*75d3a19aSMatthew G. Knepley for (p = 0; p < 4; ++p) { 829*75d3a19aSMatthew 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); 830*75d3a19aSMatthew G. Knepley } 831*75d3a19aSMatthew G. Knepley #endif 832*75d3a19aSMatthew G. Knepley /* B quad */ 833*75d3a19aSMatthew G. Knepley coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 834*75d3a19aSMatthew G. Knepley orntNew[0] = ornt[0]; 835*75d3a19aSMatthew G. Knepley coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 836*75d3a19aSMatthew G. Knepley orntNew[1] = ornt[1]; 837*75d3a19aSMatthew G. Knepley coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 838*75d3a19aSMatthew G. Knepley orntNew[2] = 0; 839*75d3a19aSMatthew G. Knepley coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3] - fMax); 840*75d3a19aSMatthew G. Knepley orntNew[3] = 0; 841*75d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 842*75d3a19aSMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 843*75d3a19aSMatthew G. Knepley #if 1 844*75d3a19aSMatthew 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); 845*75d3a19aSMatthew G. Knepley for (p = 0; p < 4; ++p) { 846*75d3a19aSMatthew 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); 847*75d3a19aSMatthew G. Knepley } 848*75d3a19aSMatthew G. Knepley #endif 849*75d3a19aSMatthew G. Knepley } 850*75d3a19aSMatthew G. Knepley /* Interior split faces have 2 vertices and the same cells as the parent */ 851*75d3a19aSMatthew G. Knepley ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 852*75d3a19aSMatthew G. Knepley ierr = PetscMalloc((2 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr); 853*75d3a19aSMatthew G. Knepley for (f = fStart; f < fMax; ++f) { 854*75d3a19aSMatthew G. Knepley const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 855*75d3a19aSMatthew G. Knepley 856*75d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 857*75d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (f - fStart)*2 + r; 858*75d3a19aSMatthew G. Knepley const PetscInt *cone, *support; 859*75d3a19aSMatthew G. Knepley PetscInt coneNew[2], coneSize, c, supportSize, s; 860*75d3a19aSMatthew G. Knepley 861*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 862*75d3a19aSMatthew G. Knepley coneNew[0] = vStartNew + (cone[0] - vStart); 863*75d3a19aSMatthew G. Knepley coneNew[1] = vStartNew + (cone[1] - vStart); 864*75d3a19aSMatthew G. Knepley coneNew[(r+1)%2] = newv; 865*75d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 866*75d3a19aSMatthew G. Knepley #if 1 867*75d3a19aSMatthew 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); 868*75d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 869*75d3a19aSMatthew 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); 870*75d3a19aSMatthew G. Knepley } 871*75d3a19aSMatthew G. Knepley #endif 872*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 873*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 874*75d3a19aSMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 875*75d3a19aSMatthew G. Knepley if (support[s] >= cMax) { 876*75d3a19aSMatthew G. Knepley supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 877*75d3a19aSMatthew G. Knepley } else { 878*75d3a19aSMatthew G. Knepley ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 879*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 880*75d3a19aSMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 881*75d3a19aSMatthew G. Knepley if (cone[c] == f) break; 882*75d3a19aSMatthew G. Knepley } 883*75d3a19aSMatthew G. Knepley supportRef[s] = cStartNew + (support[s] - cStart)*4 + (c+r)%3; 884*75d3a19aSMatthew G. Knepley } 885*75d3a19aSMatthew G. Knepley } 886*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 887*75d3a19aSMatthew G. Knepley #if 1 888*75d3a19aSMatthew 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); 889*75d3a19aSMatthew G. Knepley for (p = 0; p < supportSize; ++p) { 890*75d3a19aSMatthew 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); 891*75d3a19aSMatthew G. Knepley } 892*75d3a19aSMatthew G. Knepley #endif 893*75d3a19aSMatthew G. Knepley } 894*75d3a19aSMatthew G. Knepley } 895*75d3a19aSMatthew G. Knepley /* Interior cell faces have 2 vertices and 2 cells */ 896*75d3a19aSMatthew G. Knepley for (c = cStart; c < cMax; ++c) { 897*75d3a19aSMatthew G. Knepley const PetscInt *cone; 898*75d3a19aSMatthew G. Knepley 899*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 900*75d3a19aSMatthew G. Knepley for (r = 0; r < 3; ++r) { 901*75d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 902*75d3a19aSMatthew G. Knepley PetscInt coneNew[2]; 903*75d3a19aSMatthew G. Knepley PetscInt supportNew[2]; 904*75d3a19aSMatthew G. Knepley 905*75d3a19aSMatthew G. Knepley coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 906*75d3a19aSMatthew G. Knepley coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 907*75d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 908*75d3a19aSMatthew G. Knepley #if 1 909*75d3a19aSMatthew 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); 910*75d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 911*75d3a19aSMatthew 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); 912*75d3a19aSMatthew G. Knepley } 913*75d3a19aSMatthew G. Knepley #endif 914*75d3a19aSMatthew G. Knepley supportNew[0] = (c - cStart)*4 + (r+1)%3; 915*75d3a19aSMatthew G. Knepley supportNew[1] = (c - cStart)*4 + 3; 916*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 917*75d3a19aSMatthew G. Knepley #if 1 918*75d3a19aSMatthew 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); 919*75d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 920*75d3a19aSMatthew 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); 921*75d3a19aSMatthew G. Knepley } 922*75d3a19aSMatthew G. Knepley #endif 923*75d3a19aSMatthew G. Knepley } 924*75d3a19aSMatthew G. Knepley } 925*75d3a19aSMatthew G. Knepley /* Interior hybrid faces have 2 vertices and the same cells */ 926*75d3a19aSMatthew G. Knepley for (f = fMax; f < fEnd; ++f) { 927*75d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 928*75d3a19aSMatthew G. Knepley const PetscInt *cone; 929*75d3a19aSMatthew G. Knepley const PetscInt *support; 930*75d3a19aSMatthew G. Knepley PetscInt coneNew[2]; 931*75d3a19aSMatthew G. Knepley PetscInt supportNew[2]; 932*75d3a19aSMatthew G. Knepley PetscInt size, s, r; 933*75d3a19aSMatthew G. Knepley 934*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 935*75d3a19aSMatthew G. Knepley coneNew[0] = vStartNew + (cone[0] - vStart); 936*75d3a19aSMatthew G. Knepley coneNew[1] = vStartNew + (cone[1] - vStart); 937*75d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 938*75d3a19aSMatthew G. Knepley #if 1 939*75d3a19aSMatthew 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); 940*75d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 941*75d3a19aSMatthew 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); 942*75d3a19aSMatthew G. Knepley } 943*75d3a19aSMatthew G. Knepley #endif 944*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 945*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 946*75d3a19aSMatthew G. Knepley for (s = 0; s < size; ++s) { 947*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 948*75d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 949*75d3a19aSMatthew G. Knepley if (cone[r+2] == f) break; 950*75d3a19aSMatthew G. Knepley } 951*75d3a19aSMatthew G. Knepley supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 952*75d3a19aSMatthew G. Knepley } 953*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 954*75d3a19aSMatthew G. Knepley #if 1 955*75d3a19aSMatthew 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); 956*75d3a19aSMatthew G. Knepley for (p = 0; p < size; ++p) { 957*75d3a19aSMatthew 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); 958*75d3a19aSMatthew G. Knepley } 959*75d3a19aSMatthew G. Knepley #endif 960*75d3a19aSMatthew G. Knepley } 961*75d3a19aSMatthew G. Knepley /* Cell hybrid faces have 2 vertices and 2 cells */ 962*75d3a19aSMatthew G. Knepley for (c = cMax; c < cEnd; ++c) { 963*75d3a19aSMatthew G. Knepley const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 964*75d3a19aSMatthew G. Knepley const PetscInt *cone; 965*75d3a19aSMatthew G. Knepley PetscInt coneNew[2]; 966*75d3a19aSMatthew G. Knepley PetscInt supportNew[2]; 967*75d3a19aSMatthew G. Knepley 968*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 969*75d3a19aSMatthew G. Knepley coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 970*75d3a19aSMatthew G. Knepley coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 971*75d3a19aSMatthew G. Knepley ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 972*75d3a19aSMatthew G. Knepley #if 1 973*75d3a19aSMatthew 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); 974*75d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 975*75d3a19aSMatthew 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); 976*75d3a19aSMatthew G. Knepley } 977*75d3a19aSMatthew G. Knepley #endif 978*75d3a19aSMatthew G. Knepley supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 979*75d3a19aSMatthew G. Knepley supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 980*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 981*75d3a19aSMatthew G. Knepley #if 1 982*75d3a19aSMatthew 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); 983*75d3a19aSMatthew G. Knepley for (p = 0; p < 2; ++p) { 984*75d3a19aSMatthew 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); 985*75d3a19aSMatthew G. Knepley } 986*75d3a19aSMatthew G. Knepley #endif 987*75d3a19aSMatthew G. Knepley } 988*75d3a19aSMatthew G. Knepley /* Old vertices have identical supports */ 989*75d3a19aSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 990*75d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (v - vStart); 991*75d3a19aSMatthew G. Knepley const PetscInt *support, *cone; 992*75d3a19aSMatthew G. Knepley PetscInt size, s; 993*75d3a19aSMatthew G. Knepley 994*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 995*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 996*75d3a19aSMatthew G. Knepley for (s = 0; s < size; ++s) { 997*75d3a19aSMatthew G. Knepley if (support[s] >= fMax) { 998*75d3a19aSMatthew G. Knepley supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax); 999*75d3a19aSMatthew G. Knepley } else { 1000*75d3a19aSMatthew G. Knepley PetscInt r = 0; 1001*75d3a19aSMatthew G. Knepley 1002*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1003*75d3a19aSMatthew G. Knepley if (cone[1] == v) r = 1; 1004*75d3a19aSMatthew G. Knepley supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1005*75d3a19aSMatthew G. Knepley } 1006*75d3a19aSMatthew G. Knepley } 1007*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1008*75d3a19aSMatthew G. Knepley #if 1 1009*75d3a19aSMatthew 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); 1010*75d3a19aSMatthew G. Knepley for (p = 0; p < size; ++p) { 1011*75d3a19aSMatthew 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); 1012*75d3a19aSMatthew G. Knepley } 1013*75d3a19aSMatthew G. Knepley #endif 1014*75d3a19aSMatthew G. Knepley } 1015*75d3a19aSMatthew G. Knepley /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 1016*75d3a19aSMatthew G. Knepley for (f = fStart; f < fMax; ++f) { 1017*75d3a19aSMatthew G. Knepley const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1018*75d3a19aSMatthew G. Knepley const PetscInt *cone, *support; 1019*75d3a19aSMatthew G. Knepley PetscInt size, newSize = 2, s; 1020*75d3a19aSMatthew G. Knepley 1021*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1022*75d3a19aSMatthew G. Knepley ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1023*75d3a19aSMatthew G. Knepley supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1024*75d3a19aSMatthew G. Knepley supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1025*75d3a19aSMatthew G. Knepley for (s = 0; s < size; ++s) { 1026*75d3a19aSMatthew G. Knepley PetscInt r = 0; 1027*75d3a19aSMatthew G. Knepley 1028*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1029*75d3a19aSMatthew G. Knepley if (support[s] >= cMax) { 1030*75d3a19aSMatthew G. Knepley supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax); 1031*75d3a19aSMatthew G. Knepley 1032*75d3a19aSMatthew G. Knepley newSize += 1; 1033*75d3a19aSMatthew G. Knepley } else { 1034*75d3a19aSMatthew G. Knepley if (cone[1] == f) r = 1; 1035*75d3a19aSMatthew G. Knepley else if (cone[2] == f) r = 2; 1036*75d3a19aSMatthew G. Knepley supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1037*75d3a19aSMatthew G. Knepley supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r; 1038*75d3a19aSMatthew G. Knepley 1039*75d3a19aSMatthew G. Knepley newSize += 2; 1040*75d3a19aSMatthew G. Knepley } 1041*75d3a19aSMatthew G. Knepley } 1042*75d3a19aSMatthew G. Knepley ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1043*75d3a19aSMatthew G. Knepley #if 1 1044*75d3a19aSMatthew 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); 1045*75d3a19aSMatthew G. Knepley for (p = 0; p < newSize; ++p) { 1046*75d3a19aSMatthew 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); 1047*75d3a19aSMatthew G. Knepley } 1048*75d3a19aSMatthew G. Knepley #endif 1049*75d3a19aSMatthew G. Knepley } 1050*75d3a19aSMatthew G. Knepley ierr = PetscFree(supportRef);CHKERRQ(ierr); 1051*75d3a19aSMatthew G. Knepley break; 1052*75d3a19aSMatthew G. Knepley default: 1053*75d3a19aSMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 1054*75d3a19aSMatthew G. Knepley } 1055*75d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 1056*75d3a19aSMatthew G. Knepley } 1057*75d3a19aSMatthew G. Knepley 1058*75d3a19aSMatthew G. Knepley #undef __FUNCT__ 1059*75d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCoordinates" 1060*75d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 1061*75d3a19aSMatthew G. Knepley { 1062*75d3a19aSMatthew G. Knepley PetscSection coordSection, coordSectionNew; 1063*75d3a19aSMatthew G. Knepley Vec coordinates, coordinatesNew; 1064*75d3a19aSMatthew G. Knepley PetscScalar *coords, *coordsNew; 1065*75d3a19aSMatthew G. Knepley PetscInt dim, depth, coordSizeNew, cStart, cEnd, c, vStart, vStartNew, vEnd, v, fStart, fEnd, fMax, f; 1066*75d3a19aSMatthew G. Knepley PetscErrorCode ierr; 1067*75d3a19aSMatthew G. Knepley 1068*75d3a19aSMatthew G. Knepley PetscFunctionBegin; 1069*75d3a19aSMatthew G. Knepley ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 1070*75d3a19aSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 1071*75d3a19aSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1072*75d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1073*75d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 1074*75d3a19aSMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, NULL, &fMax, NULL, NULL);CHKERRQ(ierr); 1075*75d3a19aSMatthew G. Knepley ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr); 1076*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 1077*75d3a19aSMatthew G. Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 1078*75d3a19aSMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 1079*75d3a19aSMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dim);CHKERRQ(ierr); 1080*75d3a19aSMatthew G. Knepley ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+depthSize[0]);CHKERRQ(ierr); 1081*75d3a19aSMatthew G. Knepley if (fMax < 0) fMax = fEnd; 1082*75d3a19aSMatthew G. Knepley switch (refiner) { 1083*75d3a19aSMatthew G. Knepley case 1: 1084*75d3a19aSMatthew G. Knepley case 2: 1085*75d3a19aSMatthew G. Knepley case 3: 1086*75d3a19aSMatthew G. Knepley /* Simplicial and Hex 2D */ 1087*75d3a19aSMatthew G. Knepley /* All vertices have the dim coordinates */ 1088*75d3a19aSMatthew G. Knepley for (v = vStartNew; v < vStartNew+depthSize[0]; ++v) { 1089*75d3a19aSMatthew G. Knepley ierr = PetscSectionSetDof(coordSectionNew, v, dim);CHKERRQ(ierr); 1090*75d3a19aSMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dim);CHKERRQ(ierr); 1091*75d3a19aSMatthew G. Knepley } 1092*75d3a19aSMatthew G. Knepley ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 1093*75d3a19aSMatthew G. Knepley ierr = DMPlexSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr); 1094*75d3a19aSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 1095*75d3a19aSMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 1096*75d3a19aSMatthew G. Knepley ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr); 1097*75d3a19aSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 1098*75d3a19aSMatthew G. Knepley ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 1099*75d3a19aSMatthew G. Knepley ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr); 1100*75d3a19aSMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 1101*75d3a19aSMatthew G. Knepley ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 1102*75d3a19aSMatthew G. Knepley /* Old vertices have the same coordinates */ 1103*75d3a19aSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 1104*75d3a19aSMatthew G. Knepley const PetscInt newv = vStartNew + (v - vStart); 1105*75d3a19aSMatthew G. Knepley PetscInt off, offnew, d; 1106*75d3a19aSMatthew G. Knepley 1107*75d3a19aSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 1108*75d3a19aSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 1109*75d3a19aSMatthew G. Knepley for (d = 0; d < dim; ++d) { 1110*75d3a19aSMatthew G. Knepley coordsNew[offnew+d] = coords[off+d]; 1111*75d3a19aSMatthew G. Knepley } 1112*75d3a19aSMatthew G. Knepley } 1113*75d3a19aSMatthew G. Knepley /* Face vertices have the average of endpoint coordinates */ 1114*75d3a19aSMatthew G. Knepley for (f = fStart; f < fMax; ++f) { 1115*75d3a19aSMatthew G. Knepley const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1116*75d3a19aSMatthew G. Knepley const PetscInt *cone; 1117*75d3a19aSMatthew G. Knepley PetscInt coneSize, offA, offB, offnew, d; 1118*75d3a19aSMatthew G. Knepley 1119*75d3a19aSMatthew G. Knepley ierr = DMPlexGetConeSize(dm, f, &coneSize);CHKERRQ(ierr); 1120*75d3a19aSMatthew G. Knepley if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Face %d cone should have two vertices, not %d", f, coneSize); 1121*75d3a19aSMatthew G. Knepley ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1122*75d3a19aSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 1123*75d3a19aSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 1124*75d3a19aSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 1125*75d3a19aSMatthew G. Knepley for (d = 0; d < dim; ++d) { 1126*75d3a19aSMatthew G. Knepley coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]); 1127*75d3a19aSMatthew G. Knepley } 1128*75d3a19aSMatthew G. Knepley } 1129*75d3a19aSMatthew G. Knepley /* Just Hex 2D */ 1130*75d3a19aSMatthew G. Knepley if (refiner == 2) { 1131*75d3a19aSMatthew G. Knepley /* Cell vertices have the average of corner coordinates */ 1132*75d3a19aSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1133*75d3a19aSMatthew G. Knepley const PetscInt newv = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1134*75d3a19aSMatthew G. Knepley PetscInt *cone = NULL; 1135*75d3a19aSMatthew G. Knepley PetscInt closureSize, coneSize = 0, offA, offB, offC, offD, offnew, p, d; 1136*75d3a19aSMatthew G. Knepley 1137*75d3a19aSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 1138*75d3a19aSMatthew G. Knepley for (p = 0; p < closureSize*2; p += 2) { 1139*75d3a19aSMatthew G. Knepley const PetscInt point = cone[p]; 1140*75d3a19aSMatthew G. Knepley if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 1141*75d3a19aSMatthew G. Knepley } 1142*75d3a19aSMatthew G. Knepley if (coneSize != 4) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Quad %d cone should have four vertices, not %d", c, coneSize); 1143*75d3a19aSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 1144*75d3a19aSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 1145*75d3a19aSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, cone[2], &offC);CHKERRQ(ierr); 1146*75d3a19aSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, cone[3], &offD);CHKERRQ(ierr); 1147*75d3a19aSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 1148*75d3a19aSMatthew G. Knepley for (d = 0; d < dim; ++d) { 1149*75d3a19aSMatthew G. Knepley coordsNew[offnew+d] = 0.25*(coords[offA+d] + coords[offB+d] + coords[offC+d] + coords[offD+d]); 1150*75d3a19aSMatthew G. Knepley } 1151*75d3a19aSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 1152*75d3a19aSMatthew G. Knepley } 1153*75d3a19aSMatthew G. Knepley } 1154*75d3a19aSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 1155*75d3a19aSMatthew G. Knepley ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 1156*75d3a19aSMatthew G. Knepley ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 1157*75d3a19aSMatthew G. Knepley ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 1158*75d3a19aSMatthew G. Knepley ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 1159*75d3a19aSMatthew G. Knepley break; 1160*75d3a19aSMatthew G. Knepley default: 1161*75d3a19aSMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 1162*75d3a19aSMatthew G. Knepley } 1163*75d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 1164*75d3a19aSMatthew G. Knepley } 1165*75d3a19aSMatthew G. Knepley 1166*75d3a19aSMatthew G. Knepley #undef __FUNCT__ 1167*75d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexCreateProcessSF" 1168*75d3a19aSMatthew G. Knepley PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 1169*75d3a19aSMatthew G. Knepley { 1170*75d3a19aSMatthew G. Knepley PetscInt numRoots, numLeaves, l; 1171*75d3a19aSMatthew G. Knepley const PetscInt *localPoints; 1172*75d3a19aSMatthew G. Knepley const PetscSFNode *remotePoints; 1173*75d3a19aSMatthew G. Knepley PetscInt *localPointsNew; 1174*75d3a19aSMatthew G. Knepley PetscSFNode *remotePointsNew; 1175*75d3a19aSMatthew G. Knepley PetscInt *ranks, *ranksNew; 1176*75d3a19aSMatthew G. Knepley PetscErrorCode ierr; 1177*75d3a19aSMatthew G. Knepley 1178*75d3a19aSMatthew G. Knepley PetscFunctionBegin; 1179*75d3a19aSMatthew G. Knepley ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 1180*75d3a19aSMatthew G. Knepley ierr = PetscMalloc(numLeaves * sizeof(PetscInt), &ranks);CHKERRQ(ierr); 1181*75d3a19aSMatthew G. Knepley for (l = 0; l < numLeaves; ++l) { 1182*75d3a19aSMatthew G. Knepley ranks[l] = remotePoints[l].rank; 1183*75d3a19aSMatthew G. Knepley } 1184*75d3a19aSMatthew G. Knepley ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 1185*75d3a19aSMatthew G. Knepley ierr = PetscMalloc(numLeaves * sizeof(PetscInt), &ranksNew);CHKERRQ(ierr); 1186*75d3a19aSMatthew G. Knepley ierr = PetscMalloc(numLeaves * sizeof(PetscInt), &localPointsNew);CHKERRQ(ierr); 1187*75d3a19aSMatthew G. Knepley ierr = PetscMalloc(numLeaves * sizeof(PetscSFNode), &remotePointsNew);CHKERRQ(ierr); 1188*75d3a19aSMatthew G. Knepley for (l = 0; l < numLeaves; ++l) { 1189*75d3a19aSMatthew G. Knepley ranksNew[l] = ranks[l]; 1190*75d3a19aSMatthew G. Knepley localPointsNew[l] = l; 1191*75d3a19aSMatthew G. Knepley remotePointsNew[l].index = 0; 1192*75d3a19aSMatthew G. Knepley remotePointsNew[l].rank = ranksNew[l]; 1193*75d3a19aSMatthew G. Knepley } 1194*75d3a19aSMatthew G. Knepley ierr = PetscFree(ranks);CHKERRQ(ierr); 1195*75d3a19aSMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr); 1196*75d3a19aSMatthew G. Knepley ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 1197*75d3a19aSMatthew G. Knepley ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 1198*75d3a19aSMatthew G. Knepley ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 1199*75d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 1200*75d3a19aSMatthew G. Knepley } 1201*75d3a19aSMatthew G. Knepley 1202*75d3a19aSMatthew G. Knepley #undef __FUNCT__ 1203*75d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateSF" 1204*75d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 1205*75d3a19aSMatthew G. Knepley { 1206*75d3a19aSMatthew G. Knepley PetscSF sf, sfNew, sfProcess; 1207*75d3a19aSMatthew G. Knepley IS processRanks; 1208*75d3a19aSMatthew G. Knepley MPI_Datatype depthType; 1209*75d3a19aSMatthew G. Knepley PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 1210*75d3a19aSMatthew G. Knepley const PetscInt *localPoints, *neighbors; 1211*75d3a19aSMatthew G. Knepley const PetscSFNode *remotePoints; 1212*75d3a19aSMatthew G. Knepley PetscInt *localPointsNew; 1213*75d3a19aSMatthew G. Knepley PetscSFNode *remotePointsNew; 1214*75d3a19aSMatthew G. Knepley PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 1215*75d3a19aSMatthew 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; 1216*75d3a19aSMatthew G. Knepley PetscErrorCode ierr; 1217*75d3a19aSMatthew G. Knepley 1218*75d3a19aSMatthew G. Knepley PetscFunctionBegin; 1219*75d3a19aSMatthew G. Knepley ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 1220*75d3a19aSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 1221*75d3a19aSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1222*75d3a19aSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 1223*75d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1224*75d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 1225*75d3a19aSMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 1226*75d3a19aSMatthew G. Knepley ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 1227*75d3a19aSMatthew G. Knepley switch (refiner) { 1228*75d3a19aSMatthew G. Knepley case 3: 1229*75d3a19aSMatthew G. Knepley if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1230*75d3a19aSMatthew G. Knepley cMax = PetscMin(cEnd, cMax); 1231*75d3a19aSMatthew G. Knepley if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1232*75d3a19aSMatthew G. Knepley fMax = PetscMin(fEnd, fMax); 1233*75d3a19aSMatthew G. Knepley } 1234*75d3a19aSMatthew G. Knepley ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 1235*75d3a19aSMatthew G. Knepley ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 1236*75d3a19aSMatthew G. Knepley /* Caculate size of new SF */ 1237*75d3a19aSMatthew G. Knepley ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 1238*75d3a19aSMatthew G. Knepley if (numRoots < 0) PetscFunctionReturn(0); 1239*75d3a19aSMatthew G. Knepley for (l = 0; l < numLeaves; ++l) { 1240*75d3a19aSMatthew G. Knepley const PetscInt p = localPoints[l]; 1241*75d3a19aSMatthew G. Knepley 1242*75d3a19aSMatthew G. Knepley switch (refiner) { 1243*75d3a19aSMatthew G. Knepley case 1: 1244*75d3a19aSMatthew G. Knepley /* Simplicial 2D */ 1245*75d3a19aSMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) { 1246*75d3a19aSMatthew G. Knepley /* Old vertices stay the same */ 1247*75d3a19aSMatthew G. Knepley ++numLeavesNew; 1248*75d3a19aSMatthew G. Knepley } else if ((p >= fStart) && (p < fEnd)) { 1249*75d3a19aSMatthew G. Knepley /* Old faces add new faces and vertex */ 1250*75d3a19aSMatthew G. Knepley numLeavesNew += 1 + 2; 1251*75d3a19aSMatthew G. Knepley } else if ((p >= cStart) && (p < cEnd)) { 1252*75d3a19aSMatthew G. Knepley /* Old cells add new cells and interior faces */ 1253*75d3a19aSMatthew G. Knepley numLeavesNew += 4 + 3; 1254*75d3a19aSMatthew G. Knepley } 1255*75d3a19aSMatthew G. Knepley break; 1256*75d3a19aSMatthew G. Knepley case 2: 1257*75d3a19aSMatthew G. Knepley /* Hex 2D */ 1258*75d3a19aSMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) { 1259*75d3a19aSMatthew G. Knepley /* Old vertices stay the same */ 1260*75d3a19aSMatthew G. Knepley ++numLeavesNew; 1261*75d3a19aSMatthew G. Knepley } else if ((p >= fStart) && (p < fEnd)) { 1262*75d3a19aSMatthew G. Knepley /* Old faces add new faces and vertex */ 1263*75d3a19aSMatthew G. Knepley numLeavesNew += 1 + 2; 1264*75d3a19aSMatthew G. Knepley } else if ((p >= cStart) && (p < cEnd)) { 1265*75d3a19aSMatthew G. Knepley /* Old cells add new cells and interior faces */ 1266*75d3a19aSMatthew G. Knepley numLeavesNew += 4 + 4; 1267*75d3a19aSMatthew G. Knepley } 1268*75d3a19aSMatthew G. Knepley break; 1269*75d3a19aSMatthew G. Knepley default: 1270*75d3a19aSMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 1271*75d3a19aSMatthew G. Knepley } 1272*75d3a19aSMatthew G. Knepley } 1273*75d3a19aSMatthew G. Knepley /* Communicate depthSizes for each remote rank */ 1274*75d3a19aSMatthew G. Knepley ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 1275*75d3a19aSMatthew G. Knepley ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 1276*75d3a19aSMatthew G. Knepley ierr = PetscMalloc5((depth+1)*numNeighbors,PetscInt,&rdepthSize,numNeighbors,PetscInt,&rvStartNew,numNeighbors,PetscInt,&reStartNew,numNeighbors,PetscInt,&rfStartNew,numNeighbors,PetscInt,&rcStartNew);CHKERRQ(ierr); 1277*75d3a19aSMatthew 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); 1278*75d3a19aSMatthew G. Knepley ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 1279*75d3a19aSMatthew G. Knepley ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 1280*75d3a19aSMatthew G. Knepley ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 1281*75d3a19aSMatthew G. Knepley ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 1282*75d3a19aSMatthew G. Knepley for (n = 0; n < numNeighbors; ++n) { 1283*75d3a19aSMatthew G. Knepley ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 1284*75d3a19aSMatthew G. Knepley } 1285*75d3a19aSMatthew G. Knepley depthSizeOld[depth] = cMax; 1286*75d3a19aSMatthew G. Knepley depthSizeOld[0] = vMax; 1287*75d3a19aSMatthew G. Knepley depthSizeOld[depth-1] = fMax; 1288*75d3a19aSMatthew G. Knepley depthSizeOld[1] = eMax; 1289*75d3a19aSMatthew G. Knepley 1290*75d3a19aSMatthew G. Knepley ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 1291*75d3a19aSMatthew G. Knepley ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 1292*75d3a19aSMatthew G. Knepley 1293*75d3a19aSMatthew G. Knepley depthSizeOld[depth] = cEnd - cStart; 1294*75d3a19aSMatthew G. Knepley depthSizeOld[0] = vEnd - vStart; 1295*75d3a19aSMatthew G. Knepley depthSizeOld[depth-1] = fEnd - fStart; 1296*75d3a19aSMatthew G. Knepley depthSizeOld[1] = eEnd - eStart; 1297*75d3a19aSMatthew G. Knepley 1298*75d3a19aSMatthew G. Knepley ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 1299*75d3a19aSMatthew G. Knepley ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 1300*75d3a19aSMatthew G. Knepley for (n = 0; n < numNeighbors; ++n) { 1301*75d3a19aSMatthew G. Knepley ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 1302*75d3a19aSMatthew G. Knepley } 1303*75d3a19aSMatthew G. Knepley ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 1304*75d3a19aSMatthew G. Knepley ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 1305*75d3a19aSMatthew G. Knepley /* Calculate new point SF */ 1306*75d3a19aSMatthew G. Knepley ierr = PetscMalloc(numLeavesNew * sizeof(PetscInt), &localPointsNew);CHKERRQ(ierr); 1307*75d3a19aSMatthew G. Knepley ierr = PetscMalloc(numLeavesNew * sizeof(PetscSFNode), &remotePointsNew);CHKERRQ(ierr); 1308*75d3a19aSMatthew G. Knepley ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 1309*75d3a19aSMatthew G. Knepley for (l = 0, m = 0; l < numLeaves; ++l) { 1310*75d3a19aSMatthew G. Knepley PetscInt p = localPoints[l]; 1311*75d3a19aSMatthew G. Knepley PetscInt rp = remotePoints[l].index, n; 1312*75d3a19aSMatthew G. Knepley PetscMPIInt rrank = remotePoints[l].rank; 1313*75d3a19aSMatthew G. Knepley 1314*75d3a19aSMatthew G. Knepley ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 1315*75d3a19aSMatthew G. Knepley if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 1316*75d3a19aSMatthew G. Knepley switch (refiner) { 1317*75d3a19aSMatthew G. Knepley case 1: 1318*75d3a19aSMatthew G. Knepley /* Simplicial 2D */ 1319*75d3a19aSMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) { 1320*75d3a19aSMatthew G. Knepley /* Old vertices stay the same */ 1321*75d3a19aSMatthew G. Knepley localPointsNew[m] = vStartNew + (p - vStart); 1322*75d3a19aSMatthew G. Knepley remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 1323*75d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 1324*75d3a19aSMatthew G. Knepley ++m; 1325*75d3a19aSMatthew G. Knepley } else if ((p >= fStart) && (p < fEnd)) { 1326*75d3a19aSMatthew G. Knepley /* Old faces add new faces and vertex */ 1327*75d3a19aSMatthew G. Knepley localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 1328*75d3a19aSMatthew G. Knepley remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 1329*75d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 1330*75d3a19aSMatthew G. Knepley ++m; 1331*75d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r, ++m) { 1332*75d3a19aSMatthew G. Knepley localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 1333*75d3a19aSMatthew G. Knepley remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 1334*75d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 1335*75d3a19aSMatthew G. Knepley } 1336*75d3a19aSMatthew G. Knepley } else if ((p >= cStart) && (p < cEnd)) { 1337*75d3a19aSMatthew G. Knepley /* Old cells add new cells and interior faces */ 1338*75d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r, ++m) { 1339*75d3a19aSMatthew G. Knepley localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 1340*75d3a19aSMatthew G. Knepley remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 1341*75d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 1342*75d3a19aSMatthew G. Knepley } 1343*75d3a19aSMatthew G. Knepley for (r = 0; r < 3; ++r, ++m) { 1344*75d3a19aSMatthew G. Knepley localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 1345*75d3a19aSMatthew G. Knepley remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 1346*75d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 1347*75d3a19aSMatthew G. Knepley } 1348*75d3a19aSMatthew G. Knepley } 1349*75d3a19aSMatthew G. Knepley break; 1350*75d3a19aSMatthew G. Knepley case 2: 1351*75d3a19aSMatthew G. Knepley /* Hex 2D */ 1352*75d3a19aSMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) { 1353*75d3a19aSMatthew G. Knepley /* Old vertices stay the same */ 1354*75d3a19aSMatthew G. Knepley localPointsNew[m] = vStartNew + (p - vStart); 1355*75d3a19aSMatthew G. Knepley remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 1356*75d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 1357*75d3a19aSMatthew G. Knepley ++m; 1358*75d3a19aSMatthew G. Knepley } else if ((p >= fStart) && (p < fEnd)) { 1359*75d3a19aSMatthew G. Knepley /* Old faces add new faces and vertex */ 1360*75d3a19aSMatthew G. Knepley localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 1361*75d3a19aSMatthew G. Knepley remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 1362*75d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 1363*75d3a19aSMatthew G. Knepley ++m; 1364*75d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r, ++m) { 1365*75d3a19aSMatthew G. Knepley localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 1366*75d3a19aSMatthew G. Knepley remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 1367*75d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 1368*75d3a19aSMatthew G. Knepley } 1369*75d3a19aSMatthew G. Knepley } else if ((p >= cStart) && (p < cEnd)) { 1370*75d3a19aSMatthew G. Knepley /* Old cells add new cells and interior faces */ 1371*75d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r, ++m) { 1372*75d3a19aSMatthew G. Knepley localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 1373*75d3a19aSMatthew G. Knepley remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 1374*75d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 1375*75d3a19aSMatthew G. Knepley } 1376*75d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r, ++m) { 1377*75d3a19aSMatthew G. Knepley localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 1378*75d3a19aSMatthew G. Knepley remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r; 1379*75d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 1380*75d3a19aSMatthew G. Knepley } 1381*75d3a19aSMatthew G. Knepley } 1382*75d3a19aSMatthew G. Knepley break; 1383*75d3a19aSMatthew G. Knepley case 3: 1384*75d3a19aSMatthew G. Knepley /* Hybrid simplicial 2D */ 1385*75d3a19aSMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) { 1386*75d3a19aSMatthew G. Knepley /* Old vertices stay the same */ 1387*75d3a19aSMatthew G. Knepley localPointsNew[m] = vStartNew + (p - vStart); 1388*75d3a19aSMatthew G. Knepley remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 1389*75d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 1390*75d3a19aSMatthew G. Knepley ++m; 1391*75d3a19aSMatthew G. Knepley } else if ((p >= fStart) && (p < fMax)) { 1392*75d3a19aSMatthew G. Knepley /* Old interior faces add new faces and vertex */ 1393*75d3a19aSMatthew G. Knepley localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 1394*75d3a19aSMatthew G. Knepley remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 1395*75d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 1396*75d3a19aSMatthew G. Knepley ++m; 1397*75d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r, ++m) { 1398*75d3a19aSMatthew G. Knepley localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 1399*75d3a19aSMatthew G. Knepley remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 1400*75d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 1401*75d3a19aSMatthew G. Knepley } 1402*75d3a19aSMatthew G. Knepley } else if ((p >= fMax) && (p < fEnd)) { 1403*75d3a19aSMatthew G. Knepley /* Old hybrid faces stay the same */ 1404*75d3a19aSMatthew G. Knepley localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 1405*75d3a19aSMatthew G. Knepley remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 1406*75d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 1407*75d3a19aSMatthew G. Knepley ++m; 1408*75d3a19aSMatthew G. Knepley } else if ((p >= cStart) && (p < cMax)) { 1409*75d3a19aSMatthew G. Knepley /* Old interior cells add new cells and interior faces */ 1410*75d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r, ++m) { 1411*75d3a19aSMatthew G. Knepley localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 1412*75d3a19aSMatthew G. Knepley remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 1413*75d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 1414*75d3a19aSMatthew G. Knepley } 1415*75d3a19aSMatthew G. Knepley for (r = 0; r < 3; ++r, ++m) { 1416*75d3a19aSMatthew G. Knepley localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 1417*75d3a19aSMatthew G. Knepley remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 1418*75d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 1419*75d3a19aSMatthew G. Knepley } 1420*75d3a19aSMatthew G. Knepley } else if ((p >= cStart) && (p < cMax)) { 1421*75d3a19aSMatthew G. Knepley /* Old hybrid cells add new cells and hybrid face */ 1422*75d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r, ++m) { 1423*75d3a19aSMatthew G. Knepley localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 1424*75d3a19aSMatthew G. Knepley remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 1425*75d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 1426*75d3a19aSMatthew G. Knepley } 1427*75d3a19aSMatthew G. Knepley localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 1428*75d3a19aSMatthew 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]); 1429*75d3a19aSMatthew G. Knepley remotePointsNew[m].rank = rrank; 1430*75d3a19aSMatthew G. Knepley ++m; 1431*75d3a19aSMatthew G. Knepley } 1432*75d3a19aSMatthew G. Knepley break; 1433*75d3a19aSMatthew G. Knepley default: 1434*75d3a19aSMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 1435*75d3a19aSMatthew G. Knepley } 1436*75d3a19aSMatthew G. Knepley } 1437*75d3a19aSMatthew G. Knepley ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 1438*75d3a19aSMatthew G. Knepley ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 1439*75d3a19aSMatthew G. Knepley ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 1440*75d3a19aSMatthew G. Knepley ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 1441*75d3a19aSMatthew G. Knepley ierr = PetscFree6(depthSizeOld,rdepthSizeOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 1442*75d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 1443*75d3a19aSMatthew G. Knepley } 1444*75d3a19aSMatthew G. Knepley 1445*75d3a19aSMatthew G. Knepley #undef __FUNCT__ 1446*75d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateLabels" 1447*75d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 1448*75d3a19aSMatthew G. Knepley { 1449*75d3a19aSMatthew G. Knepley PetscInt numLabels, l; 1450*75d3a19aSMatthew G. Knepley PetscInt newp, cStart, cStartNew, cEnd, cMax, vStart, vStartNew, vEnd, vMax, fStart, fStartNew, fEnd, fMax, eStart, eEnd, eMax, r; 1451*75d3a19aSMatthew G. Knepley PetscErrorCode ierr; 1452*75d3a19aSMatthew G. Knepley 1453*75d3a19aSMatthew G. Knepley PetscFunctionBegin; 1454*75d3a19aSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1455*75d3a19aSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 1456*75d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1457*75d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 1458*75d3a19aSMatthew G. Knepley 1459*75d3a19aSMatthew G. Knepley cStartNew = 0; 1460*75d3a19aSMatthew G. Knepley vStartNew = depthSize[2]; 1461*75d3a19aSMatthew G. Knepley fStartNew = depthSize[2] + depthSize[0]; 1462*75d3a19aSMatthew G. Knepley 1463*75d3a19aSMatthew G. Knepley ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 1464*75d3a19aSMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 1465*75d3a19aSMatthew G. Knepley switch (refiner) { 1466*75d3a19aSMatthew G. Knepley case 3: 1467*75d3a19aSMatthew G. Knepley if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1468*75d3a19aSMatthew G. Knepley cMax = PetscMin(cEnd, cMax); 1469*75d3a19aSMatthew G. Knepley if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1470*75d3a19aSMatthew G. Knepley fMax = PetscMin(fEnd, fMax); 1471*75d3a19aSMatthew G. Knepley } 1472*75d3a19aSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 1473*75d3a19aSMatthew G. Knepley DMLabel label, labelNew; 1474*75d3a19aSMatthew G. Knepley const char *lname; 1475*75d3a19aSMatthew G. Knepley PetscBool isDepth; 1476*75d3a19aSMatthew G. Knepley IS valueIS; 1477*75d3a19aSMatthew G. Knepley const PetscInt *values; 1478*75d3a19aSMatthew G. Knepley PetscInt numValues, val; 1479*75d3a19aSMatthew G. Knepley 1480*75d3a19aSMatthew G. Knepley ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr); 1481*75d3a19aSMatthew G. Knepley ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 1482*75d3a19aSMatthew G. Knepley if (isDepth) continue; 1483*75d3a19aSMatthew G. Knepley ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr); 1484*75d3a19aSMatthew G. Knepley ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr); 1485*75d3a19aSMatthew G. Knepley ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 1486*75d3a19aSMatthew G. Knepley ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 1487*75d3a19aSMatthew G. Knepley ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 1488*75d3a19aSMatthew G. Knepley ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 1489*75d3a19aSMatthew G. Knepley for (val = 0; val < numValues; ++val) { 1490*75d3a19aSMatthew G. Knepley IS pointIS; 1491*75d3a19aSMatthew G. Knepley const PetscInt *points; 1492*75d3a19aSMatthew G. Knepley PetscInt numPoints, n; 1493*75d3a19aSMatthew G. Knepley 1494*75d3a19aSMatthew G. Knepley ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 1495*75d3a19aSMatthew G. Knepley ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 1496*75d3a19aSMatthew G. Knepley ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 1497*75d3a19aSMatthew G. Knepley for (n = 0; n < numPoints; ++n) { 1498*75d3a19aSMatthew G. Knepley const PetscInt p = points[n]; 1499*75d3a19aSMatthew G. Knepley switch (refiner) { 1500*75d3a19aSMatthew G. Knepley case 1: 1501*75d3a19aSMatthew G. Knepley /* Simplicial 2D */ 1502*75d3a19aSMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) { 1503*75d3a19aSMatthew G. Knepley /* Old vertices stay the same */ 1504*75d3a19aSMatthew G. Knepley newp = vStartNew + (p - vStart); 1505*75d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 1506*75d3a19aSMatthew G. Knepley } else if ((p >= fStart) && (p < fEnd)) { 1507*75d3a19aSMatthew G. Knepley /* Old faces add new faces and vertex */ 1508*75d3a19aSMatthew G. Knepley newp = vStartNew + (vEnd - vStart) + (p - fStart); 1509*75d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 1510*75d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 1511*75d3a19aSMatthew G. Knepley newp = fStartNew + (p - fStart)*2 + r; 1512*75d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 1513*75d3a19aSMatthew G. Knepley } 1514*75d3a19aSMatthew G. Knepley } else if ((p >= cStart) && (p < cEnd)) { 1515*75d3a19aSMatthew G. Knepley /* Old cells add new cells and interior faces */ 1516*75d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r) { 1517*75d3a19aSMatthew G. Knepley newp = cStartNew + (p - cStart)*4 + r; 1518*75d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 1519*75d3a19aSMatthew G. Knepley } 1520*75d3a19aSMatthew G. Knepley for (r = 0; r < 3; ++r) { 1521*75d3a19aSMatthew G. Knepley newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 1522*75d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 1523*75d3a19aSMatthew G. Knepley } 1524*75d3a19aSMatthew G. Knepley } 1525*75d3a19aSMatthew G. Knepley break; 1526*75d3a19aSMatthew G. Knepley case 2: 1527*75d3a19aSMatthew G. Knepley /* Hex 2D */ 1528*75d3a19aSMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) { 1529*75d3a19aSMatthew G. Knepley /* Old vertices stay the same */ 1530*75d3a19aSMatthew G. Knepley newp = vStartNew + (p - vStart); 1531*75d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 1532*75d3a19aSMatthew G. Knepley } else if ((p >= fStart) && (p < fEnd)) { 1533*75d3a19aSMatthew G. Knepley /* Old faces add new faces and vertex */ 1534*75d3a19aSMatthew G. Knepley newp = vStartNew + (vEnd - vStart) + (p - fStart); 1535*75d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 1536*75d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 1537*75d3a19aSMatthew G. Knepley newp = fStartNew + (p - fStart)*2 + r; 1538*75d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 1539*75d3a19aSMatthew G. Knepley } 1540*75d3a19aSMatthew G. Knepley } else if ((p >= cStart) && (p < cEnd)) { 1541*75d3a19aSMatthew G. Knepley /* Old cells add new cells and interior faces and vertex */ 1542*75d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r) { 1543*75d3a19aSMatthew G. Knepley newp = cStartNew + (p - cStart)*4 + r; 1544*75d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 1545*75d3a19aSMatthew G. Knepley } 1546*75d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r) { 1547*75d3a19aSMatthew G. Knepley newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 1548*75d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 1549*75d3a19aSMatthew G. Knepley } 1550*75d3a19aSMatthew G. Knepley newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 1551*75d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 1552*75d3a19aSMatthew G. Knepley } 1553*75d3a19aSMatthew G. Knepley break; 1554*75d3a19aSMatthew G. Knepley case 3: 1555*75d3a19aSMatthew G. Knepley /* Hybrid simplicial 2D */ 1556*75d3a19aSMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) { 1557*75d3a19aSMatthew G. Knepley /* Old vertices stay the same */ 1558*75d3a19aSMatthew G. Knepley newp = vStartNew + (p - vStart); 1559*75d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 1560*75d3a19aSMatthew G. Knepley } else if ((p >= fStart) && (p < fMax)) { 1561*75d3a19aSMatthew G. Knepley /* Old interior faces add new faces and vertex */ 1562*75d3a19aSMatthew G. Knepley newp = vStartNew + (vEnd - vStart) + (p - fStart); 1563*75d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 1564*75d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 1565*75d3a19aSMatthew G. Knepley newp = fStartNew + (p - fStart)*2 + r; 1566*75d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 1567*75d3a19aSMatthew G. Knepley } 1568*75d3a19aSMatthew G. Knepley } else if ((p >= fMax) && (p < fEnd)) { 1569*75d3a19aSMatthew G. Knepley /* Old hybrid faces stay the same */ 1570*75d3a19aSMatthew G. Knepley newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 1571*75d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 1572*75d3a19aSMatthew G. Knepley } else if ((p >= cStart) && (p < cMax)) { 1573*75d3a19aSMatthew G. Knepley /* Old interior cells add new cells and interior faces */ 1574*75d3a19aSMatthew G. Knepley for (r = 0; r < 4; ++r) { 1575*75d3a19aSMatthew G. Knepley newp = cStartNew + (p - cStart)*4 + r; 1576*75d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 1577*75d3a19aSMatthew G. Knepley } 1578*75d3a19aSMatthew G. Knepley for (r = 0; r < 3; ++r) { 1579*75d3a19aSMatthew G. Knepley newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 1580*75d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 1581*75d3a19aSMatthew G. Knepley } 1582*75d3a19aSMatthew G. Knepley } else if ((p >= cMax) && (p < cEnd)) { 1583*75d3a19aSMatthew G. Knepley /* Old hybrid cells add new cells and hybrid face */ 1584*75d3a19aSMatthew G. Knepley for (r = 0; r < 2; ++r) { 1585*75d3a19aSMatthew G. Knepley newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 1586*75d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 1587*75d3a19aSMatthew G. Knepley } 1588*75d3a19aSMatthew G. Knepley newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 1589*75d3a19aSMatthew G. Knepley ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 1590*75d3a19aSMatthew G. Knepley } 1591*75d3a19aSMatthew G. Knepley break; 1592*75d3a19aSMatthew G. Knepley default: 1593*75d3a19aSMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 1594*75d3a19aSMatthew G. Knepley } 1595*75d3a19aSMatthew G. Knepley } 1596*75d3a19aSMatthew G. Knepley ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 1597*75d3a19aSMatthew G. Knepley ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 1598*75d3a19aSMatthew G. Knepley } 1599*75d3a19aSMatthew G. Knepley ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 1600*75d3a19aSMatthew G. Knepley ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 1601*75d3a19aSMatthew G. Knepley if (0) { 1602*75d3a19aSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr); 1603*75d3a19aSMatthew G. Knepley ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 1604*75d3a19aSMatthew G. Knepley ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 1605*75d3a19aSMatthew G. Knepley } 1606*75d3a19aSMatthew G. Knepley } 1607*75d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 1608*75d3a19aSMatthew G. Knepley } 1609*75d3a19aSMatthew G. Knepley 1610*75d3a19aSMatthew G. Knepley #undef __FUNCT__ 1611*75d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexRefine_Uniform" 1612*75d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */ 1613*75d3a19aSMatthew G. Knepley PetscErrorCode DMPlexRefine_Uniform(DM dm, CellRefiner cellRefiner, DM *dmRefined) 1614*75d3a19aSMatthew G. Knepley { 1615*75d3a19aSMatthew G. Knepley DM rdm; 1616*75d3a19aSMatthew G. Knepley PetscInt *depthSize; 1617*75d3a19aSMatthew G. Knepley PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 1618*75d3a19aSMatthew G. Knepley PetscErrorCode ierr; 1619*75d3a19aSMatthew G. Knepley 1620*75d3a19aSMatthew G. Knepley PetscFunctionBegin; 1621*75d3a19aSMatthew G. Knepley ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 1622*75d3a19aSMatthew G. Knepley ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 1623*75d3a19aSMatthew G. Knepley ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 1624*75d3a19aSMatthew G. Knepley ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr); 1625*75d3a19aSMatthew G. Knepley /* Calculate number of new points of each depth */ 1626*75d3a19aSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 1627*75d3a19aSMatthew G. Knepley ierr = PetscMalloc((depth+1) * sizeof(PetscInt), &depthSize);CHKERRQ(ierr); 1628*75d3a19aSMatthew G. Knepley ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 1629*75d3a19aSMatthew G. Knepley ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 1630*75d3a19aSMatthew G. Knepley /* Step 1: Set chart */ 1631*75d3a19aSMatthew G. Knepley for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 1632*75d3a19aSMatthew G. Knepley ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 1633*75d3a19aSMatthew G. Knepley /* Step 2: Set cone/support sizes */ 1634*75d3a19aSMatthew G. Knepley ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 1635*75d3a19aSMatthew G. Knepley /* Step 3: Setup refined DM */ 1636*75d3a19aSMatthew G. Knepley ierr = DMSetUp(rdm);CHKERRQ(ierr); 1637*75d3a19aSMatthew G. Knepley /* Step 4: Set cones and supports */ 1638*75d3a19aSMatthew G. Knepley ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 1639*75d3a19aSMatthew G. Knepley /* Step 5: Stratify */ 1640*75d3a19aSMatthew G. Knepley ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 1641*75d3a19aSMatthew G. Knepley /* Step 6: Set coordinates for vertices */ 1642*75d3a19aSMatthew G. Knepley ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 1643*75d3a19aSMatthew G. Knepley /* Step 7: Create pointSF */ 1644*75d3a19aSMatthew G. Knepley ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 1645*75d3a19aSMatthew G. Knepley /* Step 8: Create labels */ 1646*75d3a19aSMatthew G. Knepley ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 1647*75d3a19aSMatthew G. Knepley ierr = PetscFree(depthSize);CHKERRQ(ierr); 1648*75d3a19aSMatthew G. Knepley 1649*75d3a19aSMatthew G. Knepley *dmRefined = rdm; 1650*75d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 1651*75d3a19aSMatthew G. Knepley } 1652*75d3a19aSMatthew G. Knepley 1653*75d3a19aSMatthew G. Knepley #undef __FUNCT__ 1654*75d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementUniform" 1655*75d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 1656*75d3a19aSMatthew G. Knepley { 1657*75d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 1658*75d3a19aSMatthew G. Knepley 1659*75d3a19aSMatthew G. Knepley PetscFunctionBegin; 1660*75d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1661*75d3a19aSMatthew G. Knepley mesh->refinementUniform = refinementUniform; 1662*75d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 1663*75d3a19aSMatthew G. Knepley } 1664*75d3a19aSMatthew G. Knepley 1665*75d3a19aSMatthew G. Knepley #undef __FUNCT__ 1666*75d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementUniform" 1667*75d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 1668*75d3a19aSMatthew G. Knepley { 1669*75d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 1670*75d3a19aSMatthew G. Knepley 1671*75d3a19aSMatthew G. Knepley PetscFunctionBegin; 1672*75d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1673*75d3a19aSMatthew G. Knepley PetscValidPointer(refinementUniform, 2); 1674*75d3a19aSMatthew G. Knepley *refinementUniform = mesh->refinementUniform; 1675*75d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 1676*75d3a19aSMatthew G. Knepley } 1677*75d3a19aSMatthew G. Knepley 1678*75d3a19aSMatthew G. Knepley #undef __FUNCT__ 1679*75d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementLimit" 1680*75d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 1681*75d3a19aSMatthew G. Knepley { 1682*75d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 1683*75d3a19aSMatthew G. Knepley 1684*75d3a19aSMatthew G. Knepley PetscFunctionBegin; 1685*75d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1686*75d3a19aSMatthew G. Knepley mesh->refinementLimit = refinementLimit; 1687*75d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 1688*75d3a19aSMatthew G. Knepley } 1689*75d3a19aSMatthew G. Knepley 1690*75d3a19aSMatthew G. Knepley #undef __FUNCT__ 1691*75d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementLimit" 1692*75d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 1693*75d3a19aSMatthew G. Knepley { 1694*75d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 1695*75d3a19aSMatthew G. Knepley 1696*75d3a19aSMatthew G. Knepley PetscFunctionBegin; 1697*75d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1698*75d3a19aSMatthew G. Knepley PetscValidPointer(refinementLimit, 2); 1699*75d3a19aSMatthew G. Knepley /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 1700*75d3a19aSMatthew G. Knepley *refinementLimit = mesh->refinementLimit; 1701*75d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 1702*75d3a19aSMatthew G. Knepley } 1703*75d3a19aSMatthew G. Knepley 1704*75d3a19aSMatthew G. Knepley #undef __FUNCT__ 1705*75d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetCellRefiner_Private" 1706*75d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetCellRefiner_Private(DM dm, CellRefiner *cellRefiner) 1707*75d3a19aSMatthew G. Knepley { 1708*75d3a19aSMatthew G. Knepley PetscInt dim, cStart, coneSize, cMax; 1709*75d3a19aSMatthew G. Knepley PetscErrorCode ierr; 1710*75d3a19aSMatthew G. Knepley 1711*75d3a19aSMatthew G. Knepley PetscFunctionBegin; 1712*75d3a19aSMatthew G. Knepley ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 1713*75d3a19aSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, NULL);CHKERRQ(ierr); 1714*75d3a19aSMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 1715*75d3a19aSMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 1716*75d3a19aSMatthew G. Knepley switch (dim) { 1717*75d3a19aSMatthew G. Knepley case 2: 1718*75d3a19aSMatthew G. Knepley switch (coneSize) { 1719*75d3a19aSMatthew G. Knepley case 3: 1720*75d3a19aSMatthew G. Knepley if (cMax >= 0) *cellRefiner = 3; /* Hybrid */ 1721*75d3a19aSMatthew G. Knepley else *cellRefiner = 1; /* Triangular */ 1722*75d3a19aSMatthew G. Knepley break; 1723*75d3a19aSMatthew G. Knepley case 4: 1724*75d3a19aSMatthew G. Knepley if (cMax >= 0) *cellRefiner = 4; /* Hybrid */ 1725*75d3a19aSMatthew G. Knepley else *cellRefiner = 2; /* Quadrilateral */ 1726*75d3a19aSMatthew G. Knepley break; 1727*75d3a19aSMatthew G. Knepley default: 1728*75d3a19aSMatthew G. Knepley SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 1729*75d3a19aSMatthew G. Knepley } 1730*75d3a19aSMatthew G. Knepley break; 1731*75d3a19aSMatthew G. Knepley default: 1732*75d3a19aSMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 1733*75d3a19aSMatthew G. Knepley } 1734*75d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 1735*75d3a19aSMatthew G. Knepley } 1736