1 #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2 #include <petscsf.h> 3 4 PETSC_STATIC_INLINE PetscErrorCode GetDepthStart_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cStart, PetscInt *fStart, PetscInt *eStart, PetscInt *vStart) 5 { 6 PetscFunctionBegin; 7 if (cStart) *cStart = 0; 8 if (vStart) *vStart = depth < 0 ? 0 : depthSize[depth]; 9 if (fStart) *fStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0]; 10 if (eStart) *eStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1]; 11 PetscFunctionReturn(0); 12 } 13 14 PETSC_STATIC_INLINE PetscErrorCode GetDepthEnd_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cEnd, PetscInt *fEnd, PetscInt *eEnd, PetscInt *vEnd) 15 { 16 PetscFunctionBegin; 17 if (cEnd) *cEnd = depth < 0 ? 0 : depthSize[depth]; 18 if (vEnd) *vEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0]; 19 if (fEnd) *fEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1]; 20 if (eEnd) *eEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1] + depthSize[1]; 21 PetscFunctionReturn(0); 22 } 23 24 /* Gets the affine map from the original cell to each subcell */ 25 PetscErrorCode CellRefinerGetAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[]) 26 { 27 PetscReal *v = NULL, *j = NULL, *invj = NULL, detJ; 28 PetscInt dim, s; 29 PetscErrorCode ierr; 30 31 PetscFunctionBegin; 32 switch (refiner) { 33 case REFINER_NOOP: break; 34 case REFINER_SIMPLEX_2D: 35 /* 36 2 37 |\ 38 | \ 39 | \ 40 | \ 41 | C \ 42 | \ 43 | \ 44 2---1---1 45 |\ D / \ 46 | 2 0 \ 47 |A \ / B \ 48 0---0-------1 49 */ 50 dim = 2; 51 if (numSubcells) *numSubcells = 4; 52 if (v0) { 53 ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr); 54 /* A */ 55 v[0+0] = -1.0; v[0+1] = -1.0; 56 j[0+0] = 0.5; j[0+1] = 0.0; 57 j[0+2] = 0.0; j[0+3] = 0.5; 58 /* B */ 59 v[2+0] = 0.0; v[2+1] = -1.0; 60 j[4+0] = 0.5; j[4+1] = 0.0; 61 j[4+2] = 0.0; j[4+3] = 0.5; 62 /* C */ 63 v[4+0] = -1.0; v[4+1] = 0.0; 64 j[8+0] = 0.5; j[8+1] = 0.0; 65 j[8+2] = 0.0; j[8+3] = 0.5; 66 /* D */ 67 v[6+0] = 0.0; v[6+1] = -1.0; 68 j[12+0] = 0.0; j[12+1] = -0.5; 69 j[12+2] = 0.5; j[12+3] = 0.5; 70 for (s = 0; s < 4; ++s) { 71 DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]); 72 DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 73 } 74 } 75 break; 76 case REFINER_HEX_2D: 77 /* 78 3---------2---------2 79 | | | 80 | D 2 C | 81 | | | 82 3----3----0----1----1 83 | | | 84 | A 0 B | 85 | | | 86 0---------0---------1 87 */ 88 dim = 2; 89 if (numSubcells) *numSubcells = 4; 90 if (v0) { 91 ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr); 92 /* A */ 93 v[0+0] = -1.0; v[0+1] = -1.0; 94 j[0+0] = 0.5; j[0+1] = 0.0; 95 j[0+2] = 0.0; j[0+3] = 0.5; 96 /* B */ 97 v[2+0] = 0.0; v[2+1] = -1.0; 98 j[4+0] = 0.5; j[4+1] = 0.0; 99 j[4+2] = 0.0; j[4+3] = 0.5; 100 /* C */ 101 v[4+0] = 0.0; v[4+1] = 0.0; 102 j[8+0] = 0.5; j[8+1] = 0.0; 103 j[8+2] = 0.0; j[8+3] = 0.5; 104 /* D */ 105 v[6+0] = -1.0; v[6+1] = 0.0; 106 j[12+0] = 0.5; j[12+1] = 0.0; 107 j[12+2] = 0.0; j[12+3] = 0.5; 108 for (s = 0; s < 4; ++s) { 109 DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]); 110 DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 111 } 112 } 113 break; 114 case REFINER_HEX_3D: 115 /* 116 Bottom (viewed from top) Top 117 1---------2---------2 7---------2---------6 118 | | | | | | 119 | B 2 C | | H 2 G | 120 | | | | | | 121 3----3----0----1----1 3----3----0----1----1 122 | | | | | | 123 | A 0 D | | E 0 F | 124 | | | | | | 125 0---------0---------3 4---------0---------5 126 */ 127 break; 128 dim = 3; 129 if (numSubcells) *numSubcells = 8; 130 if (v0) { 131 ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr); 132 /* A */ 133 v[0+0] = -1.0; v[0+1] = -1.0; v[0+2] = -1.0; 134 j[0+0] = 0.5; j[0+1] = 0.0; j[0+2] = 0.0; 135 j[0+3] = 0.0; j[0+4] = 0.5; j[0+5] = 0.0; 136 j[0+6] = 0.0; j[0+7] = 0.0; j[0+8] = 0.5; 137 /* B */ 138 v[3+0] = -1.0; v[3+1] = 0.0; v[3+2] = -1.0; 139 j[9+0] = 0.5; j[9+1] = 0.0; j[9+2] = 0.0; 140 j[9+3] = 0.0; j[9+4] = 0.5; j[9+5] = 0.0; 141 j[9+6] = 0.0; j[9+7] = 0.0; j[9+8] = 0.5; 142 /* C */ 143 v[6+0] = 0.0; v[6+1] = 0.0; v[6+2] = -1.0; 144 j[18+0] = 0.5; j[18+1] = 0.0; j[18+2] = 0.0; 145 j[18+3] = 0.0; j[18+4] = 0.5; j[18+5] = 0.0; 146 j[18+6] = 0.0; j[18+7] = 0.0; j[18+8] = 0.5; 147 /* D */ 148 v[9+0] = 0.0; v[9+1] = -1.0; v[9+2] = -1.0; 149 j[27+0] = 0.5; j[27+1] = 0.0; j[27+2] = 0.0; 150 j[27+3] = 0.0; j[27+4] = 0.5; j[27+5] = 0.0; 151 j[27+6] = 0.0; j[27+7] = 0.0; j[27+8] = 0.5; 152 /* E */ 153 v[12+0] = -1.0; v[12+1] = -1.0; v[12+2] = 0.0; 154 j[36+0] = 0.5; j[36+1] = 0.0; j[36+2] = 0.0; 155 j[36+3] = 0.0; j[36+4] = 0.5; j[36+5] = 0.0; 156 j[36+6] = 0.0; j[36+7] = 0.0; j[36+8] = 0.5; 157 /* F */ 158 v[15+0] = 0.0; v[15+1] = -1.0; v[15+2] = 0.0; 159 j[45+0] = 0.5; j[45+1] = 0.0; j[45+2] = 0.0; 160 j[45+3] = 0.0; j[45+4] = 0.5; j[45+5] = 0.0; 161 j[45+6] = 0.0; j[45+7] = 0.0; j[45+8] = 0.5; 162 /* G */ 163 v[18+0] = 0.0; v[18+1] = 0.0; v[18+2] = 0.0; 164 j[54+0] = 0.5; j[54+1] = 0.0; j[54+2] = 0.0; 165 j[54+3] = 0.0; j[54+4] = 0.5; j[54+5] = 0.0; 166 j[54+6] = 0.0; j[54+7] = 0.0; j[54+8] = 0.5; 167 /* H */ 168 v[21+0] = -1.0; v[21+1] = 0.0; v[21+2] = 0.0; 169 j[63+0] = 0.5; j[63+1] = 0.0; j[63+2] = 0.0; 170 j[63+3] = 0.0; j[63+4] = 0.5; j[63+5] = 0.0; 171 j[63+6] = 0.0; j[63+7] = 0.0; j[63+8] = 0.5; 172 for (s = 0; s < 8; ++s) { 173 DMPlex_Det3D_Internal(&detJ, &j[s*dim*dim]); 174 DMPlex_Invert3D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 175 } 176 } 177 default: 178 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", refiner); 179 } 180 if (v0) {*v0 = v; *jac = j; *invjac = invj;} 181 PetscFunctionReturn(0); 182 } 183 184 PetscErrorCode CellRefinerRestoreAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[]) 185 { 186 PetscErrorCode ierr; 187 188 PetscFunctionBegin; 189 ierr = PetscFree3(*v0,*jac,*invjac);CHKERRQ(ierr); 190 PetscFunctionReturn(0); 191 } 192 193 /* Should this be here or in the DualSpace somehow? */ 194 PetscErrorCode CellRefinerInCellTest_Internal(CellRefiner refiner, const PetscReal point[], PetscBool *inside) 195 { 196 PetscReal sum = 0.0; 197 PetscInt d; 198 199 PetscFunctionBegin; 200 *inside = PETSC_TRUE; 201 switch (refiner) { 202 case REFINER_NOOP: break; 203 case REFINER_SIMPLEX_2D: 204 for (d = 0; d < 2; ++d) { 205 if (point[d] < -1.0) {*inside = PETSC_FALSE; break;} 206 sum += point[d]; 207 } 208 if (sum > 1.0e-10) {*inside = PETSC_FALSE; break;} 209 break; 210 case REFINER_HEX_2D: 211 for (d = 0; d < 2; ++d) if ((point[d] < -1.00000000001) || (point[d] > 1.000000000001)) {*inside = PETSC_FALSE; break;} 212 break; 213 default: 214 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", refiner); 215 } 216 PetscFunctionReturn(0); 217 } 218 219 static PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[]) 220 { 221 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 222 PetscErrorCode ierr; 223 224 PetscFunctionBegin; 225 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 226 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 227 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 228 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 229 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 230 switch (refiner) { 231 case REFINER_NOOP: 232 break; 233 case REFINER_SIMPLEX_1D: 234 depthSize[0] = vEnd - vStart + cEnd - cStart; /* Add a vertex on every cell. */ 235 depthSize[1] = 2*(cEnd - cStart); /* Split every cell in 2. */ 236 break; 237 case REFINER_SIMPLEX_2D: 238 depthSize[0] = vEnd - vStart + fEnd - fStart; /* Add a vertex on every face */ 239 depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */ 240 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 241 break; 242 case REFINER_HYBRID_SIMPLEX_2D: 243 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 244 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 245 depthSize[0] = vEnd - vStart + fMax - fStart; /* Add a vertex on every face, but not hybrid faces */ 246 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 */ 247 depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax); /* Interior cells split into 4 cells, hybrid cells split into 2 cells */ 248 break; 249 case REFINER_SIMPLEX_TO_HEX_2D: 250 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 251 depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */ 252 depthSize[2] = 3*(cEnd - cStart); /* Every cell split into 3 cells */ 253 break; 254 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 255 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 256 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 257 depthSize[1] = 2*(fEnd - fStart) + 3*(cMax - cStart) + 4*(cEnd - cMax); /* Every face is split into 2 faces and 3 faces are added for each cell. 4 for each hybrid cell */ 258 depthSize[2] = 3*(cMax - cStart) + 4*(cEnd - cMax); /* Every cell split into 3 cells, hybrid cells split in 4 */ 259 break; 260 case REFINER_HEX_2D: 261 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 262 depthSize[1] = 2*(fEnd - fStart) + 4*(cEnd - cStart); /* Every face is split into 2 faces and 4 faces are added for each cell */ 263 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 264 break; 265 case REFINER_HYBRID_HEX_2D: 266 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 267 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 268 /* Quadrilateral */ 269 depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart; /* Add a vertex on every face and cell */ 270 depthSize[1] = 2*(fMax - fStart) + 4*(cMax - cStart); /* Every face is split into 2 faces, and 4 faces are added for each cell */ 271 depthSize[2] = 4*(cMax - cStart); /* Every cell split into 4 cells */ 272 /* Segment Prisms */ 273 depthSize[0] += 0; /* No hybrid vertices */ 274 depthSize[1] += (fEnd - fMax) + (cEnd - cMax); /* Every hybrid face remains and 1 faces is added for each hybrid cell */ 275 depthSize[2] += 2*(cEnd - cMax); /* Every hybrid cell split into 2 cells */ 276 break; 277 case REFINER_SIMPLEX_3D: 278 depthSize[0] = vEnd - vStart + eEnd - eStart; /* Add a vertex on every edge */ 279 depthSize[1] = 2*(eEnd - eStart) + 3*(fEnd - fStart) + (cEnd - cStart); /* Every edge is split into 2 edges, 3 edges are added for each face, and 1 edge for each cell */ 280 depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart); /* Every face split into 4 faces and 8 faces are added for each cell */ 281 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 282 break; 283 case REFINER_HYBRID_SIMPLEX_3D: 284 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 285 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 286 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 287 /* Tetrahedra */ 288 depthSize[0] = vEnd - vStart + eMax - eStart; /* Add a vertex on every interior edge */ 289 depthSize[1] = 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart); /* Every interior edge split into 2 edges, 3 edges added for each interior face, 1 edge for each interior cell */ 290 depthSize[2] = 4*(fMax - fStart) + 8*(cMax - cStart); /* Every interior face split into 4 faces, 8 faces added for each interior cell */ 291 depthSize[3] = 8*(cMax - cStart); /* Every interior cell split into 8 cells */ 292 /* Triangular Prisms */ 293 depthSize[0] += 0; /* No hybrid vertices */ 294 depthSize[1] += (eEnd - eMax) + (fEnd - fMax); /* Every hybrid edge remains, 1 edge for every hybrid face */ 295 depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */ 296 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 297 break; 298 case REFINER_SIMPLEX_TO_HEX_3D: 299 depthSize[0] = vEnd - vStart + fEnd - fStart + eEnd - eStart + cEnd - cStart; /* Add a vertex on every face, edge and cell */ 300 depthSize[1] = 2*(eEnd - eStart) + 3*(fEnd - fStart) + 4*(cEnd - cStart); /* Every edge is split into 2 edges, 3 edges are added for each face, and 4 for each cell */ 301 depthSize[2] = 3*(fEnd - fStart) + 6*(cEnd - cStart); /* Every face is split into 3 faces and 6 faces are added for each cell */ 302 depthSize[3] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 303 break; 304 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 305 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 306 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 307 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 308 /* Tetrahedra */ 309 depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every interior edge, face and cell */ 310 depthSize[1] = 2*(eMax - eStart) + 3*(fMax - fStart) + 4*(cMax - cStart); /* Every interior edge split into 2 edges, 3 edges added for each interior face, 4 edges for each interior cell */ 311 depthSize[2] = 3*(fMax - fStart) + 6*(cMax - cStart); /* Every interior face split into 3 faces, 6 faces added for each interior cell */ 312 depthSize[3] = 4*(cMax - cStart); /* Every interior cell split into 8 cells */ 313 /* Triangular Prisms */ 314 depthSize[0] += 0; /* No hybrid vertices */ 315 depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and cell */ 316 depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */ 317 depthSize[3] += 3*(cEnd - cMax); /* Every hybrid cell split into 3 cells */ 318 break; 319 case REFINER_HEX_3D: 320 depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */ 321 depthSize[1] = 2*(eEnd - eStart) + 4*(fEnd - fStart) + 6*(cEnd - cStart); /* Every edge is split into 2 edge, 4 edges are added for each face, and 6 edges for each cell */ 322 depthSize[2] = 4*(fEnd - fStart) + 12*(cEnd - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 323 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 324 break; 325 case REFINER_HYBRID_HEX_3D: 326 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 327 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 328 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 329 /* Hexahedra */ 330 depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */ 331 depthSize[1] = 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart); /* Every edge is split into 2 edge, 4 edges are added for each face, and 6 edges for each cell */ 332 depthSize[2] = 4*(fMax - fStart) + 12*(cMax - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 333 depthSize[3] = 8*(cMax - cStart); /* Every cell split into 8 cells */ 334 /* Quadrilateral Prisms */ 335 depthSize[0] += 0; /* No hybrid vertices */ 336 depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */ 337 depthSize[2] += 2*(fEnd - fMax) + 4*(cEnd - cMax); /* Every hybrid face split into 2 faces and 4 faces are added for each hybrid cell */ 338 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 339 break; 340 default: 341 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", refiner); 342 } 343 PetscFunctionReturn(0); 344 } 345 346 /* Return triangle edge for orientation o, if it is r for o == 0 */ 347 PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) { 348 return (o < 0 ? 2-(o+r) : o+r)%3; 349 } 350 PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) { 351 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 352 } 353 354 /* Return triangle subface for orientation o, if it is r for o == 0 */ 355 PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) { 356 return (o < 0 ? 3-(o+r) : o+r)%3; 357 } 358 PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) { 359 return (o < 0 ? 3-(o+s) : 3+s-o)%3; 360 } 361 362 /* Return the interior edge number connecting the midpoints of the triangle edges r 363 and r+1 in the transitive closure for triangle orientation o */ 364 PETSC_STATIC_INLINE PetscInt GetTriMidEdge_Static(PetscInt o, PetscInt r) { 365 return (o < 0 ? 1-(o+r) : o+r)%3; 366 } 367 PETSC_STATIC_INLINE PetscInt GetTriMidEdgeInverse_Static(PetscInt o, PetscInt s) { 368 return (o < 0 ? 1-(o+s) : 3+s-o)%3; 369 } 370 371 /* Return the interior edge number connecting the midpoint of the triangle edge r 372 (in the transitive closure) and the vertex in the interior of the face for triangle orientation o */ 373 PETSC_STATIC_INLINE PetscInt GetTriInteriorEdge_Static(PetscInt o, PetscInt r) { 374 return (o < 0 ? 2-(o+r) : o+r)%3; 375 } 376 PETSC_STATIC_INLINE PetscInt GetTriInteriorEdgeInverse_Static(PetscInt o, PetscInt s) { 377 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 378 } 379 380 /* Return quad edge for orientation o, if it is r for o == 0 */ 381 PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) { 382 return (o < 0 ? 3-(o+r) : o+r)%4; 383 } 384 PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) { 385 return (o < 0 ? 3-(o+s) : 4+s-o)%4; 386 } 387 388 /* Return quad subface for orientation o, if it is r for o == 0 */ 389 PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) { 390 return (o < 0 ? 4-(o+r) : o+r)%4; 391 } 392 PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) { 393 return (o < 0 ? 4-(o+s) : 4+s-o)%4; 394 } 395 396 static PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt cStart, PetscInt cEnd) 397 { 398 IS cIS; 399 PetscErrorCode ierr; 400 401 PetscFunctionBegin; 402 ierr = ISCreateStride(PETSC_COMM_SELF, cEnd - cStart, cStart, 1, &cIS);CHKERRQ(ierr); 403 ierr = DMLabelSetStratumIS(label, value, cIS);CHKERRQ(ierr); 404 ierr = ISDestroy(&cIS);CHKERRQ(ierr); 405 PetscFunctionReturn(0); 406 } 407 408 static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 409 { 410 PetscInt depth, cStart, cStartNew, cEnd, cEndNew, cMax, c, vStart, vStartNew, vEnd, vEndNew, vMax, v, fStart, fStartNew, fEnd, fEndNew, fMax, f, eStart, eStartNew, eEnd, eEndNew, eMax, e, r; 411 DMLabel depthLabel; 412 PetscErrorCode ierr; 413 414 PetscFunctionBegin; 415 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 416 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 417 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 418 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 419 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 420 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 421 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 422 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 423 ierr = DMCreateLabel(rdm,"depth");CHKERRQ(ierr); 424 ierr = DMPlexGetDepthLabel(rdm,&depthLabel);CHKERRQ(ierr); 425 ierr = DMLabelSetStratumBounds(depthLabel, 0, vStartNew, vEndNew);CHKERRQ(ierr); 426 if (depth > 2) ierr = DMLabelSetStratumBounds(depthLabel, 1, eStartNew, eEndNew);CHKERRQ(ierr); 427 if (depth > 1) ierr = DMLabelSetStratumBounds(depthLabel, depth - 1, fStartNew, fEndNew);CHKERRQ(ierr); 428 if (depth > 0) ierr = DMLabelSetStratumBounds(depthLabel, depth, cStartNew, cEndNew);CHKERRQ(ierr); 429 { 430 DM_Plex *plex = (DM_Plex *) rdm->data; 431 ierr = PetscObjectStateGet((PetscObject) depthLabel, &plex->depthState);CHKERRQ(ierr); 432 } 433 if (!refiner) PetscFunctionReturn(0); 434 switch (refiner) { 435 case REFINER_SIMPLEX_1D: 436 /* All cells have 2 vertices */ 437 for (c = cStart; c < cEnd; ++c) { 438 for (r = 0; r < 2; ++r) { 439 const PetscInt newp = cStartNew + (c - cStart)*2 + r; 440 441 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 442 } 443 } 444 /* Old vertices have identical supports */ 445 for (v = vStart; v < vEnd; ++v) { 446 const PetscInt newp = vStartNew + (v - vStart); 447 PetscInt size; 448 449 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 450 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 451 } 452 /* Cell vertices have support 2 */ 453 for (c = cStart; c < cEnd; ++c) { 454 const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart); 455 456 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 457 } 458 break; 459 case REFINER_SIMPLEX_2D: 460 /* All cells have 3 faces */ 461 for (c = cStart; c < cEnd; ++c) { 462 for (r = 0; r < 4; ++r) { 463 const PetscInt newp = (c - cStart)*4 + r; 464 465 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 466 } 467 } 468 /* Split faces have 2 vertices and the same cells as the parent */ 469 for (f = fStart; f < fEnd; ++f) { 470 for (r = 0; r < 2; ++r) { 471 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 472 PetscInt size; 473 474 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 475 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 476 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 477 } 478 } 479 /* Interior faces have 2 vertices and 2 cells */ 480 for (c = cStart; c < cEnd; ++c) { 481 for (r = 0; r < 3; ++r) { 482 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 483 484 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 485 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 486 } 487 } 488 /* Old vertices have identical supports */ 489 for (v = vStart; v < vEnd; ++v) { 490 const PetscInt newp = vStartNew + (v - vStart); 491 PetscInt size; 492 493 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 494 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 495 } 496 /* Face vertices have 2 + cells*2 supports */ 497 for (f = fStart; f < fEnd; ++f) { 498 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 499 PetscInt size; 500 501 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 502 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr); 503 } 504 break; 505 case REFINER_SIMPLEX_TO_HEX_2D: 506 /* All cells have 4 faces */ 507 for (c = cStart; c < cEnd; ++c) { 508 for (r = 0; r < 3; ++r) { 509 const PetscInt newp = (c - cStart)*3 + r; 510 511 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 512 } 513 } 514 /* Split faces have 2 vertices and the same cells as the parent */ 515 for (f = fStart; f < fEnd; ++f) { 516 for (r = 0; r < 2; ++r) { 517 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 518 PetscInt size; 519 520 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 521 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 522 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 523 } 524 } 525 /* Interior faces have 2 vertices and 2 cells */ 526 for (c = cStart; c < cEnd; ++c) { 527 for (r = 0; r < 3; ++r) { 528 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 529 530 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 531 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 532 } 533 } 534 /* Old vertices have identical supports */ 535 for (v = vStart; v < vEnd; ++v) { 536 const PetscInt newp = vStartNew + (v - vStart); 537 PetscInt size; 538 539 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 540 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 541 } 542 /* Split-face vertices have cells + 2 supports */ 543 for (f = fStart; f < fEnd; ++f) { 544 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 545 PetscInt size; 546 547 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 548 ierr = DMPlexSetSupportSize(rdm, newp, size + 2);CHKERRQ(ierr); 549 } 550 /* Interior vertices have 3 supports */ 551 for (c = cStart; c < cEnd; ++c) { 552 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 553 554 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 555 } 556 break; 557 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 558 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 559 /* the mesh is no longer hybrid */ 560 cMax = PetscMin(cEnd, cMax); 561 /* All cells have 4 faces */ 562 for (c = cStart; c < cMax; ++c) { 563 for (r = 0; r < 3; ++r) { 564 const PetscInt newp = (c - cStart)*3 + r; 565 566 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 567 } 568 } 569 for (c = cMax; c < cEnd; ++c) { 570 for (r = 0; r < 4; ++r) { 571 const PetscInt newp = (cMax - cStart)*3 + (c - cMax)*4 + r; 572 573 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 574 } 575 } 576 /* Split faces have 2 vertices and the same cells as the parent */ 577 for (f = fStart; f < fEnd; ++f) { 578 for (r = 0; r < 2; ++r) { 579 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 580 PetscInt size; 581 582 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 583 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 584 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 585 } 586 } 587 /* Interior faces have 2 vertices and 2 cells */ 588 for (c = cStart; c < cMax; ++c) { 589 for (r = 0; r < 3; ++r) { 590 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 591 592 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 593 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 594 } 595 } 596 /* Hybrid interior faces have 2 vertices and 2 cells */ 597 for (c = cMax; c < cEnd; ++c) { 598 for (r = 0; r < 4; ++r) { 599 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + r; 600 601 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 602 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 603 } 604 } 605 /* Old vertices have identical supports */ 606 for (v = vStart; v < vEnd; ++v) { 607 const PetscInt newp = vStartNew + (v - vStart); 608 PetscInt size; 609 610 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 611 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 612 } 613 /* Split-face vertices have cells + 2 supports */ 614 for (f = fStart; f < fEnd; ++f) { 615 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 616 PetscInt size; 617 618 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 619 ierr = DMPlexSetSupportSize(rdm, newp, size + 2);CHKERRQ(ierr); 620 } 621 /* Interior vertices have 3 supports */ 622 for (c = cStart; c < cMax; ++c) { 623 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 624 625 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 626 } 627 /* Hybrid interior vertices have 4 supports */ 628 for (c = cMax; c < cEnd; ++c) { 629 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 630 631 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 632 } 633 break; 634 case REFINER_HEX_2D: 635 /* All cells have 4 faces */ 636 for (c = cStart; c < cEnd; ++c) { 637 for (r = 0; r < 4; ++r) { 638 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 639 640 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 641 } 642 } 643 /* Split faces have 2 vertices and the same cells as the parent */ 644 for (f = fStart; f < fEnd; ++f) { 645 for (r = 0; r < 2; ++r) { 646 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 647 PetscInt size; 648 649 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 650 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 651 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 652 } 653 } 654 /* Interior faces have 2 vertices and 2 cells */ 655 for (c = cStart; c < cEnd; ++c) { 656 for (r = 0; r < 4; ++r) { 657 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 658 659 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 660 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 661 } 662 } 663 /* Old vertices have identical supports */ 664 for (v = vStart; v < vEnd; ++v) { 665 const PetscInt newp = vStartNew + (v - vStart); 666 PetscInt size; 667 668 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 669 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 670 } 671 /* Face vertices have 2 + cells supports */ 672 for (f = fStart; f < fEnd; ++f) { 673 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 674 PetscInt size; 675 676 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 677 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 678 } 679 /* Cell vertices have 4 supports */ 680 for (c = cStart; c < cEnd; ++c) { 681 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 682 683 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 684 } 685 break; 686 case REFINER_HYBRID_SIMPLEX_2D: 687 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 688 cMax = PetscMin(cEnd, cMax); 689 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 690 fMax = PetscMin(fEnd, fMax); 691 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 692 /* Interior cells have 3 faces */ 693 for (c = cStart; c < cMax; ++c) { 694 for (r = 0; r < 4; ++r) { 695 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 696 697 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 698 } 699 } 700 /* Hybrid cells have 4 faces */ 701 for (c = cMax; c < cEnd; ++c) { 702 for (r = 0; r < 2; ++r) { 703 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 704 705 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 706 } 707 } 708 /* Interior split faces have 2 vertices and the same cells as the parent */ 709 for (f = fStart; f < fMax; ++f) { 710 for (r = 0; r < 2; ++r) { 711 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 712 PetscInt size; 713 714 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 715 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 716 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 717 } 718 } 719 /* Interior cell faces have 2 vertices and 2 cells */ 720 for (c = cStart; c < cMax; ++c) { 721 for (r = 0; r < 3; ++r) { 722 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 723 724 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 725 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 726 } 727 } 728 /* Hybrid faces have 2 vertices and the same cells */ 729 for (f = fMax; f < fEnd; ++f) { 730 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 731 PetscInt size; 732 733 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 734 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 735 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 736 } 737 /* Hybrid cell faces have 2 vertices and 2 cells */ 738 for (c = cMax; c < cEnd; ++c) { 739 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 740 741 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 742 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 743 } 744 /* Old vertices have identical supports */ 745 for (v = vStart; v < vEnd; ++v) { 746 const PetscInt newp = vStartNew + (v - vStart); 747 PetscInt size; 748 749 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 750 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 751 } 752 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 753 for (f = fStart; f < fMax; ++f) { 754 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 755 const PetscInt *support; 756 PetscInt size, newSize = 2, s; 757 758 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 759 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 760 for (s = 0; s < size; ++s) { 761 if (support[s] >= cMax) newSize += 1; 762 else newSize += 2; 763 } 764 ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr); 765 } 766 break; 767 case REFINER_HYBRID_HEX_2D: 768 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 769 cMax = PetscMin(cEnd, cMax); 770 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 771 fMax = PetscMin(fEnd, fMax); 772 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 773 /* Interior cells have 4 faces */ 774 for (c = cStart; c < cMax; ++c) { 775 for (r = 0; r < 4; ++r) { 776 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 777 778 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 779 } 780 } 781 /* Hybrid cells have 4 faces */ 782 for (c = cMax; c < cEnd; ++c) { 783 for (r = 0; r < 2; ++r) { 784 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 785 786 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 787 } 788 } 789 /* Interior split faces have 2 vertices and the same cells as the parent */ 790 for (f = fStart; f < fMax; ++f) { 791 for (r = 0; r < 2; ++r) { 792 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 793 PetscInt size; 794 795 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 796 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 797 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 798 } 799 } 800 /* Interior cell faces have 2 vertices and 2 cells */ 801 for (c = cStart; c < cMax; ++c) { 802 for (r = 0; r < 4; ++r) { 803 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 804 805 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 806 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 807 } 808 } 809 /* Hybrid faces have 2 vertices and the same cells */ 810 for (f = fMax; f < fEnd; ++f) { 811 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 812 PetscInt size; 813 814 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 815 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 816 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 817 } 818 /* Hybrid cell faces have 2 vertices and 2 cells */ 819 for (c = cMax; c < cEnd; ++c) { 820 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 821 822 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 823 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 824 } 825 /* Old vertices have identical supports */ 826 for (v = vStart; v < vEnd; ++v) { 827 const PetscInt newp = vStartNew + (v - vStart); 828 PetscInt size; 829 830 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 831 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 832 } 833 /* Face vertices have 2 + cells supports */ 834 for (f = fStart; f < fMax; ++f) { 835 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 836 PetscInt size; 837 838 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 839 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 840 } 841 /* Cell vertices have 4 supports */ 842 for (c = cStart; c < cMax; ++c) { 843 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 844 845 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 846 } 847 break; 848 case REFINER_SIMPLEX_3D: 849 /* All cells have 4 faces */ 850 for (c = cStart; c < cEnd; ++c) { 851 for (r = 0; r < 8; ++r) { 852 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 853 854 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 855 } 856 } 857 /* Split faces have 3 edges and the same cells as the parent */ 858 for (f = fStart; f < fEnd; ++f) { 859 for (r = 0; r < 4; ++r) { 860 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 861 PetscInt size; 862 863 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 864 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 865 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 866 } 867 } 868 /* Interior cell faces have 3 edges and 2 cells */ 869 for (c = cStart; c < cEnd; ++c) { 870 for (r = 0; r < 8; ++r) { 871 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r; 872 873 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 874 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 875 } 876 } 877 /* Split edges have 2 vertices and the same faces */ 878 for (e = eStart; e < eEnd; ++e) { 879 for (r = 0; r < 2; ++r) { 880 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 881 PetscInt size; 882 883 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 884 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 885 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 886 } 887 } 888 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 889 for (f = fStart; f < fEnd; ++f) { 890 for (r = 0; r < 3; ++r) { 891 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 892 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 893 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 894 895 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 896 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 897 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 898 for (s = 0; s < supportSize; ++s) { 899 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 900 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 901 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 902 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 903 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 904 er = GetTriMidEdgeInverse_Static(ornt[c], r); 905 if (er == eint[c]) { 906 intFaces += 1; 907 } else { 908 intFaces += 2; 909 } 910 } 911 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 912 } 913 } 914 /* Interior cell edges have 2 vertices and 4 faces */ 915 for (c = cStart; c < cEnd; ++c) { 916 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 917 918 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 919 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 920 } 921 /* Old vertices have identical supports */ 922 for (v = vStart; v < vEnd; ++v) { 923 const PetscInt newp = vStartNew + (v - vStart); 924 PetscInt size; 925 926 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 927 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 928 } 929 /* Edge vertices have 2 + faces*2 + cells*0/1 supports */ 930 for (e = eStart; e < eEnd; ++e) { 931 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 932 PetscInt size, *star = NULL, starSize, s, cellSize = 0; 933 934 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 935 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 936 for (s = 0; s < starSize*2; s += 2) { 937 const PetscInt *cone, *ornt; 938 PetscInt e01, e23; 939 940 if ((star[s] >= cStart) && (star[s] < cEnd)) { 941 /* Check edge 0-1 */ 942 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 943 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 944 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 945 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 946 /* Check edge 2-3 */ 947 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 948 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 949 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 950 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 951 if ((e01 == e) || (e23 == e)) ++cellSize; 952 } 953 } 954 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 955 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr); 956 } 957 break; 958 case REFINER_HYBRID_SIMPLEX_3D: 959 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart), 960 eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 961 /* Interior cells have 4 faces */ 962 for (c = cStart; c < cMax; ++c) { 963 for (r = 0; r < 8; ++r) { 964 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 965 966 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 967 } 968 } 969 /* Hybrid cells have 5 faces */ 970 for (c = cMax; c < cEnd; ++c) { 971 for (r = 0; r < 4; ++r) { 972 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 973 974 ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr); 975 } 976 } 977 /* Interior split faces have 3 edges and the same cells as the parent */ 978 for (f = fStart; f < fMax; ++f) { 979 for (r = 0; r < 4; ++r) { 980 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 981 PetscInt size; 982 983 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 984 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 985 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 986 } 987 } 988 /* Interior cell faces have 3 edges and 2 cells */ 989 for (c = cStart; c < cMax; ++c) { 990 for (r = 0; r < 8; ++r) { 991 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r; 992 993 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 994 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 995 } 996 } 997 /* Hybrid split faces have 4 edges and the same cells as the parent */ 998 for (f = fMax; f < fEnd; ++f) { 999 for (r = 0; r < 2; ++r) { 1000 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 1001 PetscInt size; 1002 1003 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1004 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1005 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1006 } 1007 } 1008 /* Hybrid cells faces have 4 edges and 2 cells */ 1009 for (c = cMax; c < cEnd; ++c) { 1010 for (r = 0; r < 3; ++r) { 1011 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 1012 1013 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1014 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1015 } 1016 } 1017 /* Interior split edges have 2 vertices and the same faces */ 1018 for (e = eStart; e < eMax; ++e) { 1019 for (r = 0; r < 2; ++r) { 1020 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1021 PetscInt size; 1022 1023 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1024 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1025 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1026 } 1027 } 1028 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 1029 for (f = fStart; f < fMax; ++f) { 1030 for (r = 0; r < 3; ++r) { 1031 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 1032 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 1033 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 1034 1035 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1036 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1037 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1038 for (s = 0; s < supportSize; ++s) { 1039 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1040 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1041 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1042 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 1043 if (support[s] < cMax) { 1044 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 1045 er = GetTriMidEdgeInverse_Static(ornt[c], r); 1046 if (er == eint[c]) { 1047 intFaces += 1; 1048 } else { 1049 intFaces += 2; 1050 } 1051 } else { 1052 intFaces += 1; 1053 } 1054 } 1055 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 1056 } 1057 } 1058 /* Interior cell edges have 2 vertices and 4 faces */ 1059 for (c = cStart; c < cMax; ++c) { 1060 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 1061 1062 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1063 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1064 } 1065 /* Hybrid edges have 2 vertices and the same faces */ 1066 for (e = eMax; e < eEnd; ++e) { 1067 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 1068 PetscInt size; 1069 1070 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1071 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1072 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1073 } 1074 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 1075 for (f = fMax; f < fEnd; ++f) { 1076 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 1077 PetscInt size; 1078 1079 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1080 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1081 ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr); 1082 } 1083 /* Interior vertices have identical supports */ 1084 for (v = vStart; v < vEnd; ++v) { 1085 const PetscInt newp = vStartNew + (v - vStart); 1086 PetscInt size; 1087 1088 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1089 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1090 } 1091 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 1092 for (e = eStart; e < eMax; ++e) { 1093 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1094 const PetscInt *support; 1095 PetscInt size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0; 1096 1097 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1098 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 1099 for (s = 0; s < size; ++s) { 1100 if (support[s] < fMax) faceSize += 2; 1101 else faceSize += 1; 1102 } 1103 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 1104 for (s = 0; s < starSize*2; s += 2) { 1105 const PetscInt *cone, *ornt; 1106 PetscInt e01, e23; 1107 1108 if ((star[s] >= cStart) && (star[s] < cMax)) { 1109 /* Check edge 0-1 */ 1110 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 1111 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 1112 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 1113 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 1114 /* Check edge 2-3 */ 1115 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 1116 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 1117 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 1118 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 1119 if ((e01 == e) || (e23 == e)) ++cellSize; 1120 } 1121 } 1122 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 1123 ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr); 1124 } 1125 break; 1126 case REFINER_SIMPLEX_TO_HEX_3D: 1127 /* All cells have 6 faces */ 1128 for (c = cStart; c < cEnd; ++c) { 1129 for (r = 0; r < 4; ++r) { 1130 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 1131 1132 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1133 } 1134 } 1135 /* Split faces have 4 edges and the same cells as the parent */ 1136 for (f = fStart; f < fEnd; ++f) { 1137 for (r = 0; r < 3; ++r) { 1138 const PetscInt newp = fStartNew + (f - fStart)*3 + r; 1139 PetscInt size; 1140 1141 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1142 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1143 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1144 } 1145 } 1146 /* Interior cell faces have 4 edges and 2 cells */ 1147 for (c = cStart; c < cEnd; ++c) { 1148 for (r = 0; r < 6; ++r) { 1149 const PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + r; 1150 1151 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1152 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1153 } 1154 } 1155 /* Split edges have 2 vertices and the same faces */ 1156 for (e = eStart; e < eEnd; ++e) { 1157 for (r = 0; r < 2; ++r) { 1158 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1159 PetscInt size; 1160 1161 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1162 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1163 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1164 } 1165 } 1166 /* Face edges have 2 vertices and 2 + cell faces supports */ 1167 for (f = fStart; f < fEnd; ++f) { 1168 for (r = 0; r < 3; ++r) { 1169 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 1170 PetscInt size; 1171 1172 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1173 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1174 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1175 } 1176 } 1177 /* Interior cell edges have 2 vertices and 3 faces */ 1178 for (c = cStart; c < cEnd; ++c) { 1179 for (r = 0; r < 4; ++r) { 1180 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r; 1181 1182 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1183 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 1184 } 1185 } 1186 /* Old vertices have identical supports */ 1187 for (v = vStart; v < vEnd; ++v) { 1188 const PetscInt newp = vStartNew + (v - vStart); 1189 PetscInt size; 1190 1191 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1192 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1193 } 1194 /* Edge vertices have 2 + faces supports */ 1195 for (e = eStart; e < eEnd; ++e) { 1196 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1197 PetscInt size; 1198 1199 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1200 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1201 } 1202 /* Face vertices have 3 + cells supports */ 1203 for (f = fStart; f < fEnd; ++f) { 1204 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart; 1205 PetscInt size; 1206 1207 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1208 ierr = DMPlexSetSupportSize(rdm, newp, 3 + size);CHKERRQ(ierr); 1209 } 1210 /* Interior cell vertices have 4 supports */ 1211 for (c = cStart; c < cEnd; ++c) { 1212 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + fEnd - fStart + c - cStart; 1213 1214 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1215 } 1216 break; 1217 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 1218 /* the mesh is no longer hybrid */ 1219 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1220 cMax = PetscMin(cEnd, cMax); 1221 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1222 fMax = PetscMin(fEnd, fMax); 1223 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 1224 eMax = PetscMin(eEnd, eMax); 1225 /* All cells have 6 faces */ 1226 for (c = cStart; c < cMax; ++c) { 1227 for (r = 0; r < 4; ++r) { 1228 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 1229 1230 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1231 } 1232 } 1233 for (c = cMax; c < cEnd; ++c) { 1234 for (r = 0; r < 3; ++r) { 1235 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + r; 1236 1237 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1238 } 1239 } 1240 /* Interior split faces have 4 edges and the same cells as the parent */ 1241 for (f = fStart; f < fMax; ++f) { 1242 for (r = 0; r < 3; ++r) { 1243 const PetscInt newp = fStartNew + (f - fStart)*3 + r; 1244 PetscInt size; 1245 1246 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1247 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1248 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1249 } 1250 } 1251 /* Interior cell faces have 4 edges and 2 cells */ 1252 for (c = cStart; c < cMax; ++c) { 1253 for (r = 0; r < 6; ++r) { 1254 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + r; 1255 1256 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1257 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1258 } 1259 } 1260 /* Hybrid split faces have 4 edges and the same cells as the parent */ 1261 for (f = fMax; f < fEnd; ++f) { 1262 for (r = 0; r < 2; ++r) { 1263 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f - fMax)*2 + r; 1264 PetscInt size; 1265 1266 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1267 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1268 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1269 } 1270 } 1271 /* Hybrid cell faces have 4 edges and 2 cells */ 1272 for (c = cMax; c < cEnd; ++c) { 1273 for (r = 0; r < 3; ++r) { 1274 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 1275 1276 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1277 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1278 } 1279 } 1280 /* Interior split edges have 2 vertices and the same faces */ 1281 for (e = eStart; e < eMax; ++e) { 1282 for (r = 0; r < 2; ++r) { 1283 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1284 PetscInt size; 1285 1286 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1287 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1288 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1289 } 1290 } 1291 /* Interior face edges have 2 vertices and 2 + cell faces supports */ 1292 for (f = fStart; f < fMax; ++f) { 1293 for (r = 0; r < 3; ++r) { 1294 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 1295 PetscInt size; 1296 1297 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1298 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1299 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1300 } 1301 } 1302 /* Interior cell edges have 2 vertices and 3 faces */ 1303 for (c = cStart; c < cMax; ++c) { 1304 for (r = 0; r < 4; ++r) { 1305 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + r; 1306 1307 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1308 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 1309 } 1310 } 1311 /* Hybrid edges have 2 vertices and the same faces */ 1312 for (e = eMax; e < eEnd; ++e) { 1313 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (e - eMax); 1314 PetscInt size; 1315 1316 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1317 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1318 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1319 } 1320 /* Hybrid face edges have 2 vertices and 2+cells faces */ 1321 for (f = fMax; f < fEnd; ++f) { 1322 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax); 1323 PetscInt size; 1324 1325 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1326 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1327 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1328 } 1329 /* Hybrid cell edges have 2 vertices and 3 faces */ 1330 for (c = cMax; c < cEnd; ++c) { 1331 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 1332 1333 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1334 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 1335 } 1336 /* Old vertices have identical supports */ 1337 for (v = vStart; v < vEnd; ++v) { 1338 const PetscInt newp = vStartNew + (v - vStart); 1339 PetscInt size; 1340 1341 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1342 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1343 } 1344 /* Interior edge vertices have 2 + faces supports */ 1345 for (e = eStart; e < eMax; ++e) { 1346 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1347 PetscInt size; 1348 1349 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1350 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1351 } 1352 /* Interior face vertices have 3 + cells supports */ 1353 for (f = fStart; f < fMax; ++f) { 1354 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + f - fStart; 1355 PetscInt size; 1356 1357 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1358 ierr = DMPlexSetSupportSize(rdm, newp, 3 + size);CHKERRQ(ierr); 1359 } 1360 /* Interior cell vertices have 4 supports */ 1361 for (c = cStart; c < cMax; ++c) { 1362 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + c - cStart; 1363 1364 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1365 } 1366 break; 1367 case REFINER_HEX_3D: 1368 /* All cells have 6 faces */ 1369 for (c = cStart; c < cEnd; ++c) { 1370 for (r = 0; r < 8; ++r) { 1371 const PetscInt newp = (c - cStart)*8 + r; 1372 1373 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1374 } 1375 } 1376 /* Split faces have 4 edges and the same cells as the parent */ 1377 for (f = fStart; f < fEnd; ++f) { 1378 for (r = 0; r < 4; ++r) { 1379 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 1380 PetscInt size; 1381 1382 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1383 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1384 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1385 } 1386 } 1387 /* Interior faces have 4 edges and 2 cells */ 1388 for (c = cStart; c < cEnd; ++c) { 1389 for (r = 0; r < 12; ++r) { 1390 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 1391 1392 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1393 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1394 } 1395 } 1396 /* Split edges have 2 vertices and the same faces as the parent */ 1397 for (e = eStart; e < eEnd; ++e) { 1398 for (r = 0; r < 2; ++r) { 1399 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1400 PetscInt size; 1401 1402 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1403 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1404 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1405 } 1406 } 1407 /* Face edges have 2 vertices and 2+cells faces */ 1408 for (f = fStart; f < fEnd; ++f) { 1409 for (r = 0; r < 4; ++r) { 1410 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 1411 PetscInt size; 1412 1413 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1414 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1415 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1416 } 1417 } 1418 /* Cell edges have 2 vertices and 4 faces */ 1419 for (c = cStart; c < cEnd; ++c) { 1420 for (r = 0; r < 6; ++r) { 1421 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 1422 1423 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1424 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1425 } 1426 } 1427 /* Old vertices have identical supports */ 1428 for (v = vStart; v < vEnd; ++v) { 1429 const PetscInt newp = vStartNew + (v - vStart); 1430 PetscInt size; 1431 1432 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1433 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1434 } 1435 /* Edge vertices have 2 + faces supports */ 1436 for (e = eStart; e < eEnd; ++e) { 1437 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1438 PetscInt size; 1439 1440 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1441 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1442 } 1443 /* Face vertices have 4 + cells supports */ 1444 for (f = fStart; f < fEnd; ++f) { 1445 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 1446 PetscInt size; 1447 1448 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1449 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 1450 } 1451 /* Cell vertices have 6 supports */ 1452 for (c = cStart; c < cEnd; ++c) { 1453 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 1454 1455 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 1456 } 1457 break; 1458 case REFINER_HYBRID_HEX_3D: 1459 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart), 1460 eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 1461 /* Interior cells have 6 faces */ 1462 for (c = cStart; c < cMax; ++c) { 1463 for (r = 0; r < 8; ++r) { 1464 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 1465 1466 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1467 } 1468 } 1469 /* Hybrid cells have 6 faces */ 1470 for (c = cMax; c < cEnd; ++c) { 1471 for (r = 0; r < 4; ++r) { 1472 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 1473 1474 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1475 } 1476 } 1477 /* Interior split faces have 4 edges and the same cells as the parent */ 1478 for (f = fStart; f < fMax; ++f) { 1479 for (r = 0; r < 4; ++r) { 1480 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 1481 PetscInt size; 1482 1483 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1484 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1485 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1486 } 1487 } 1488 /* Interior cell faces have 4 edges and 2 cells */ 1489 for (c = cStart; c < cMax; ++c) { 1490 for (r = 0; r < 12; ++r) { 1491 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 1492 1493 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1494 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1495 } 1496 } 1497 /* Hybrid split faces have 4 edges and the same cells as the parent */ 1498 for (f = fMax; f < fEnd; ++f) { 1499 for (r = 0; r < 2; ++r) { 1500 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 1501 PetscInt size; 1502 1503 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1504 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1505 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1506 } 1507 } 1508 /* Hybrid cells faces have 4 edges and 2 cells */ 1509 for (c = cMax; c < cEnd; ++c) { 1510 for (r = 0; r < 4; ++r) { 1511 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r; 1512 1513 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1514 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1515 } 1516 } 1517 /* Interior split edges have 2 vertices and the same faces as the parent */ 1518 for (e = eStart; e < eMax; ++e) { 1519 for (r = 0; r < 2; ++r) { 1520 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1521 PetscInt size; 1522 1523 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1524 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1525 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1526 } 1527 } 1528 /* Interior face edges have 2 vertices and 2+cells faces */ 1529 for (f = fStart; f < fMax; ++f) { 1530 for (r = 0; r < 4; ++r) { 1531 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 1532 PetscInt size; 1533 1534 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1535 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1536 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1537 } 1538 } 1539 /* Interior cell edges have 2 vertices and 4 faces */ 1540 for (c = cStart; c < cMax; ++c) { 1541 for (r = 0; r < 6; ++r) { 1542 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 1543 1544 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1545 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1546 } 1547 } 1548 /* Hybrid edges have 2 vertices and the same faces */ 1549 for (e = eMax; e < eEnd; ++e) { 1550 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 1551 PetscInt size; 1552 1553 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1554 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1555 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1556 } 1557 /* Hybrid face edges have 2 vertices and 2+cells faces */ 1558 for (f = fMax; f < fEnd; ++f) { 1559 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 1560 PetscInt size; 1561 1562 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1563 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1564 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1565 } 1566 /* Hybrid cell edges have 2 vertices and 4 faces */ 1567 for (c = cMax; c < cEnd; ++c) { 1568 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 1569 1570 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1571 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1572 } 1573 /* Interior vertices have identical supports */ 1574 for (v = vStart; v < vEnd; ++v) { 1575 const PetscInt newp = vStartNew + (v - vStart); 1576 PetscInt size; 1577 1578 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1579 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1580 } 1581 /* Interior edge vertices have 2 + faces supports */ 1582 for (e = eStart; e < eMax; ++e) { 1583 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1584 PetscInt size; 1585 1586 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1587 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1588 } 1589 /* Interior face vertices have 4 + cells supports */ 1590 for (f = fStart; f < fMax; ++f) { 1591 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 1592 PetscInt size; 1593 1594 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1595 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 1596 } 1597 /* Interior cell vertices have 6 supports */ 1598 for (c = cStart; c < cMax; ++c) { 1599 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 1600 1601 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 1602 } 1603 break; 1604 default: 1605 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", refiner); 1606 } 1607 PetscFunctionReturn(0); 1608 } 1609 1610 static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 1611 { 1612 const PetscInt *faces, cellInd[4] = {0, 1, 2, 3}; 1613 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 1614 PetscInt cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew, fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew; 1615 PetscInt depth, maxSupportSize, *supportRef, c, f, e, v, r; 1616 #if defined(PETSC_USE_DEBUG) 1617 PetscInt p; 1618 #endif 1619 PetscErrorCode ierr; 1620 1621 PetscFunctionBegin; 1622 if (!refiner) PetscFunctionReturn(0); 1623 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 1624 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1625 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 1626 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1627 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 1628 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 1629 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 1630 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 1631 switch (refiner) { 1632 case REFINER_SIMPLEX_1D: 1633 /* Max support size of refined mesh is 2 */ 1634 ierr = PetscMalloc1(2, &supportRef);CHKERRQ(ierr); 1635 /* All cells have 2 vertices */ 1636 for (c = cStart; c < cEnd; ++c) { 1637 const PetscInt newv = vStartNew + (vEnd - vStart) + (c - cStart); 1638 1639 for (r = 0; r < 2; ++r) { 1640 const PetscInt newp = cStartNew + (c - cStart)*2 + r; 1641 const PetscInt *cone; 1642 PetscInt coneNew[2]; 1643 1644 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1645 coneNew[0] = vStartNew + (cone[0] - vStart); 1646 coneNew[1] = vStartNew + (cone[1] - vStart); 1647 coneNew[(r+1)%2] = newv; 1648 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1649 #if defined(PETSC_USE_DEBUG) 1650 if ((newp < cStartNew) || (newp >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp, cStartNew, cEndNew); 1651 for (p = 0; p < 2; ++p) { 1652 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 1653 } 1654 #endif 1655 } 1656 } 1657 /* Old vertices have identical supports */ 1658 for (v = vStart; v < vEnd; ++v) { 1659 const PetscInt newp = vStartNew + (v - vStart); 1660 const PetscInt *support, *cone; 1661 PetscInt size, s; 1662 1663 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1664 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1665 for (s = 0; s < size; ++s) { 1666 PetscInt r = 0; 1667 1668 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1669 if (cone[1] == v) r = 1; 1670 supportRef[s] = cStartNew + (support[s] - cStart)*2 + r; 1671 } 1672 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1673 #if defined(PETSC_USE_DEBUG) 1674 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 1675 for (p = 0; p < size; ++p) { 1676 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportRef[p], cStartNew, cEndNew); 1677 } 1678 #endif 1679 } 1680 /* Cell vertices have support of 2 cells */ 1681 for (c = cStart; c < cEnd; ++c) { 1682 const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart); 1683 1684 supportRef[0] = cStartNew + (c - cStart)*2 + 0; 1685 supportRef[1] = cStartNew + (c - cStart)*2 + 1; 1686 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1687 #if defined(PETSC_USE_DEBUG) 1688 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 1689 for (p = 0; p < 2; ++p) { 1690 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportRef[p], cStartNew, cEndNew); 1691 } 1692 #endif 1693 } 1694 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1695 break; 1696 case REFINER_SIMPLEX_2D: 1697 /* 1698 2 1699 |\ 1700 | \ 1701 | \ 1702 | \ 1703 | C \ 1704 | \ 1705 | \ 1706 2---1---1 1707 |\ D / \ 1708 | 2 0 \ 1709 |A \ / B \ 1710 0---0-------1 1711 */ 1712 /* All cells have 3 faces */ 1713 for (c = cStart; c < cEnd; ++c) { 1714 const PetscInt newp = cStartNew + (c - cStart)*4; 1715 const PetscInt *cone, *ornt; 1716 PetscInt coneNew[3], orntNew[3]; 1717 1718 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1719 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1720 /* A triangle */ 1721 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1722 orntNew[0] = ornt[0]; 1723 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1724 orntNew[1] = -2; 1725 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1726 orntNew[2] = ornt[2]; 1727 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1728 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1729 #if defined(PETSC_USE_DEBUG) 1730 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+0, cStartNew, cEndNew); 1731 for (p = 0; p < 3; ++p) { 1732 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 1733 } 1734 #endif 1735 /* B triangle */ 1736 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1737 orntNew[0] = ornt[0]; 1738 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1739 orntNew[1] = ornt[1]; 1740 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1741 orntNew[2] = -2; 1742 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1743 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1744 #if defined(PETSC_USE_DEBUG) 1745 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+1, cStartNew, cEndNew); 1746 for (p = 0; p < 3; ++p) { 1747 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 1748 } 1749 #endif 1750 /* C triangle */ 1751 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1752 orntNew[0] = -2; 1753 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1754 orntNew[1] = ornt[1]; 1755 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1756 orntNew[2] = ornt[2]; 1757 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1758 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1759 #if defined(PETSC_USE_DEBUG) 1760 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+2, cStartNew, cEndNew); 1761 for (p = 0; p < 3; ++p) { 1762 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 1763 } 1764 #endif 1765 /* D triangle */ 1766 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1767 orntNew[0] = 0; 1768 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1769 orntNew[1] = 0; 1770 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1771 orntNew[2] = 0; 1772 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1773 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1774 #if defined(PETSC_USE_DEBUG) 1775 if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+3, cStartNew, cEndNew); 1776 for (p = 0; p < 3; ++p) { 1777 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 1778 } 1779 #endif 1780 } 1781 /* Split faces have 2 vertices and the same cells as the parent */ 1782 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1783 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1784 for (f = fStart; f < fEnd; ++f) { 1785 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1786 1787 for (r = 0; r < 2; ++r) { 1788 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1789 const PetscInt *cone, *ornt, *support; 1790 PetscInt coneNew[2], coneSize, c, supportSize, s; 1791 1792 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1793 coneNew[0] = vStartNew + (cone[0] - vStart); 1794 coneNew[1] = vStartNew + (cone[1] - vStart); 1795 coneNew[(r+1)%2] = newv; 1796 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1797 #if defined(PETSC_USE_DEBUG) 1798 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1799 for (p = 0; p < 2; ++p) { 1800 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 1801 } 1802 #endif 1803 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1804 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1805 for (s = 0; s < supportSize; ++s) { 1806 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1807 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1808 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1809 for (c = 0; c < coneSize; ++c) { 1810 if (cone[c] == f) break; 1811 } 1812 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1813 } 1814 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1815 #if defined(PETSC_USE_DEBUG) 1816 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1817 for (p = 0; p < supportSize; ++p) { 1818 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportRef[p], cStartNew, cEndNew); 1819 } 1820 #endif 1821 } 1822 } 1823 /* Interior faces have 2 vertices and 2 cells */ 1824 for (c = cStart; c < cEnd; ++c) { 1825 const PetscInt *cone; 1826 1827 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1828 for (r = 0; r < 3; ++r) { 1829 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 1830 PetscInt coneNew[2]; 1831 PetscInt supportNew[2]; 1832 1833 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1834 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1835 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1836 #if defined(PETSC_USE_DEBUG) 1837 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1838 for (p = 0; p < 2; ++p) { 1839 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 1840 } 1841 #endif 1842 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1843 supportNew[1] = (c - cStart)*4 + 3; 1844 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1845 #if defined(PETSC_USE_DEBUG) 1846 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1847 for (p = 0; p < 2; ++p) { 1848 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 1849 } 1850 #endif 1851 } 1852 } 1853 /* Old vertices have identical supports */ 1854 for (v = vStart; v < vEnd; ++v) { 1855 const PetscInt newp = vStartNew + (v - vStart); 1856 const PetscInt *support, *cone; 1857 PetscInt size, s; 1858 1859 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1860 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1861 for (s = 0; s < size; ++s) { 1862 PetscInt r = 0; 1863 1864 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1865 if (cone[1] == v) r = 1; 1866 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1867 } 1868 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1869 #if defined(PETSC_USE_DEBUG) 1870 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 1871 for (p = 0; p < size; ++p) { 1872 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 1873 } 1874 #endif 1875 } 1876 /* Face vertices have 2 + cells*2 supports */ 1877 for (f = fStart; f < fEnd; ++f) { 1878 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1879 const PetscInt *cone, *support; 1880 PetscInt size, s; 1881 1882 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1883 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1884 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1885 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1886 for (s = 0; s < size; ++s) { 1887 PetscInt r = 0; 1888 1889 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1890 if (cone[1] == f) r = 1; 1891 else if (cone[2] == f) r = 2; 1892 supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1893 supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 1894 } 1895 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1896 #if defined(PETSC_USE_DEBUG) 1897 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 1898 for (p = 0; p < 2+size*2; ++p) { 1899 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 1900 } 1901 #endif 1902 } 1903 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1904 break; 1905 case REFINER_SIMPLEX_TO_HEX_2D: 1906 /* 1907 2 1908 |\ 1909 | \ 1910 | \ 1911 | \ 1912 | C \ 1913 | \ 1914 2 1 1915 |\ / \ 1916 | 2 1 \ 1917 | \/ \ 1918 | | \ 1919 |A | B \ 1920 | 0 \ 1921 | | \ 1922 0---0----------1 1923 */ 1924 /* All cells have 4 faces */ 1925 for (c = cStart; c < cEnd; ++c) { 1926 const PetscInt newp = cStartNew + (c - cStart)*3; 1927 const PetscInt *cone, *ornt; 1928 PetscInt coneNew[4], orntNew[4]; 1929 1930 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1931 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1932 /* A quad */ 1933 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1934 orntNew[0] = ornt[0]; 1935 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1936 orntNew[1] = 0; 1937 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1938 orntNew[2] = -2; 1939 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1940 orntNew[3] = ornt[2]; 1941 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1942 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1943 #if defined(PETSC_USE_DEBUG) 1944 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+0, cStartNew, cEndNew); 1945 for (p = 0; p < 4; ++p) { 1946 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 1947 } 1948 #endif 1949 /* B quad */ 1950 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1951 orntNew[0] = ornt[0]; 1952 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1953 orntNew[1] = ornt[1]; 1954 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1955 orntNew[2] = 0; 1956 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1957 orntNew[3] = -2; 1958 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1959 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1960 #if defined(PETSC_USE_DEBUG) 1961 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+1, cStartNew, cEndNew); 1962 for (p = 0; p < 4; ++p) { 1963 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 1964 } 1965 #endif 1966 /* C quad */ 1967 coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1968 orntNew[0] = ornt[1]; 1969 coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1970 orntNew[1] = ornt[2]; 1971 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1972 orntNew[2] = 0; 1973 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1974 orntNew[3] = -2; 1975 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1976 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1977 #if defined(PETSC_USE_DEBUG) 1978 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+2, cStartNew, cEndNew); 1979 for (p = 0; p < 4; ++p) { 1980 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 1981 } 1982 #endif 1983 } 1984 /* Split faces have 2 vertices and the same cells as the parent */ 1985 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1986 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1987 for (f = fStart; f < fEnd; ++f) { 1988 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1989 1990 for (r = 0; r < 2; ++r) { 1991 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1992 const PetscInt *cone, *ornt, *support; 1993 PetscInt coneNew[2], coneSize, c, supportSize, s; 1994 1995 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1996 coneNew[0] = vStartNew + (cone[0] - vStart); 1997 coneNew[1] = vStartNew + (cone[1] - vStart); 1998 coneNew[(r+1)%2] = newv; 1999 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2000 #if defined(PETSC_USE_DEBUG) 2001 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2002 for (p = 0; p < 2; ++p) { 2003 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 2004 } 2005 #endif 2006 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2007 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2008 for (s = 0; s < supportSize; ++s) { 2009 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2010 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2011 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2012 for (c = 0; c < coneSize; ++c) { 2013 if (cone[c] == f) break; 2014 } 2015 supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2016 } 2017 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2018 #if defined(PETSC_USE_DEBUG) 2019 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2020 for (p = 0; p < supportSize; ++p) { 2021 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportRef[p], cStartNew, cEndNew); 2022 } 2023 #endif 2024 } 2025 } 2026 /* Interior faces have 2 vertices and 2 cells */ 2027 for (c = cStart; c < cEnd; ++c) { 2028 const PetscInt *cone; 2029 2030 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2031 for (r = 0; r < 3; ++r) { 2032 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 2033 PetscInt coneNew[2]; 2034 PetscInt supportNew[2]; 2035 2036 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2037 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2038 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2039 #if defined(PETSC_USE_DEBUG) 2040 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2041 for (p = 0; p < 2; ++p) { 2042 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 2043 } 2044 #endif 2045 supportNew[0] = (c - cStart)*3 + r%3; 2046 supportNew[1] = (c - cStart)*3 + (r+1)%3; 2047 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2048 #if defined(PETSC_USE_DEBUG) 2049 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2050 for (p = 0; p < 2; ++p) { 2051 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 2052 } 2053 #endif 2054 } 2055 } 2056 /* Old vertices have identical supports */ 2057 for (v = vStart; v < vEnd; ++v) { 2058 const PetscInt newp = vStartNew + (v - vStart); 2059 const PetscInt *support, *cone; 2060 PetscInt size, s; 2061 2062 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2063 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2064 for (s = 0; s < size; ++s) { 2065 PetscInt r = 0; 2066 2067 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2068 if (cone[1] == v) r = 1; 2069 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2070 } 2071 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2072 #if defined(PETSC_USE_DEBUG) 2073 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2074 for (p = 0; p < size; ++p) { 2075 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 2076 } 2077 #endif 2078 } 2079 /* Split-face vertices have cells + 2 supports */ 2080 for (f = fStart; f < fEnd; ++f) { 2081 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2082 const PetscInt *cone, *support; 2083 PetscInt size, s; 2084 2085 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2086 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2087 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2088 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2089 for (s = 0; s < size; ++s) { 2090 PetscInt r = 0; 2091 2092 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2093 if (cone[1] == f) r = 1; 2094 else if (cone[2] == f) r = 2; 2095 supportRef[2+s+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 2096 } 2097 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2098 #if defined(PETSC_USE_DEBUG) 2099 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2100 for (p = 0; p < 2+size; ++p) { 2101 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 2102 } 2103 #endif 2104 } 2105 /* Interior vertices have 3 supports */ 2106 for (c = cStart; c < cEnd; ++c) { 2107 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 2108 2109 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2110 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2111 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2112 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2113 } 2114 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2115 break; 2116 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 2117 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 2118 cMax = PetscMin(cEnd, cMax); 2119 for (c = cStart; c < cMax; ++c) { 2120 const PetscInt newp = cStartNew + (c - cStart)*3; 2121 const PetscInt *cone, *ornt; 2122 PetscInt coneNew[4], orntNew[4]; 2123 2124 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2125 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2126 /* A quad */ 2127 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2128 orntNew[0] = ornt[0]; 2129 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2130 orntNew[1] = 0; 2131 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2132 orntNew[2] = -2; 2133 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2134 orntNew[3] = ornt[2]; 2135 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2136 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2137 #if defined(PETSC_USE_DEBUG) 2138 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+0, cStartNew, cEndNew); 2139 for (p = 0; p < 4; ++p) { 2140 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 2141 } 2142 #endif 2143 /* B quad */ 2144 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2145 orntNew[0] = ornt[0]; 2146 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2147 orntNew[1] = ornt[1]; 2148 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2149 orntNew[2] = 0; 2150 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2151 orntNew[3] = -2; 2152 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2153 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2154 #if defined(PETSC_USE_DEBUG) 2155 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+1, cStartNew, cEndNew); 2156 for (p = 0; p < 4; ++p) { 2157 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 2158 } 2159 #endif 2160 /* C quad */ 2161 coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2162 orntNew[0] = ornt[1]; 2163 coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2164 orntNew[1] = ornt[2]; 2165 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2166 orntNew[2] = 0; 2167 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2168 orntNew[3] = -2; 2169 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2170 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2171 #if defined(PETSC_USE_DEBUG) 2172 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+2, cStartNew, cEndNew); 2173 for (p = 0; p < 4; ++p) { 2174 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 2175 } 2176 #endif 2177 } 2178 /* 2179 2---------1---------3 2180 | | | 2181 | D 1 C | 2182 | | | 2183 2----2----0----3----3 2184 | | | 2185 | A 0 B | 2186 | | | 2187 0---------0---------1 2188 */ 2189 /* Parent cells are input as prisms but children are quads, since the mesh is no longer hybrid */ 2190 for (c = cMax; c < cEnd; ++c) { 2191 const PetscInt newp = cStartNew + (cMax - cStart)*3 + (c - cMax)*4; 2192 const PetscInt newpt = (cMax - cStart)*3 + (c - cMax)*4; 2193 const PetscInt *cone, *ornt; 2194 PetscInt coneNew[4], orntNew[4]; 2195 2196 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2197 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2198 /* A quad */ 2199 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2200 orntNew[0] = ornt[0]; 2201 coneNew[1] = fStartNew + (fEnd - fStart)*2 + newpt + 0; 2202 orntNew[1] = 0; 2203 coneNew[2] = fStartNew + (fEnd - fStart)*2 + newpt + 2; 2204 orntNew[2] = -2; 2205 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2206 orntNew[3] = ornt[2] < 0 ? 0 : -2; 2207 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2208 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2209 #if defined(PETSC_USE_DEBUG) 2210 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+0, cStartNew, cEndNew); 2211 for (p = 0; p < 4; ++p) { 2212 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 2213 } 2214 #endif 2215 /* B quad */ 2216 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2217 orntNew[0] = ornt[0]; 2218 coneNew[1] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 2219 orntNew[1] = ornt[3]; 2220 coneNew[2] = fStartNew + (fEnd - fStart)*2 + newpt + 3; 2221 orntNew[2] = 0; 2222 coneNew[3] = fStartNew + (fEnd - fStart)*2 + newpt + 0; 2223 orntNew[3] = -2; 2224 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2225 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2226 #if defined(PETSC_USE_DEBUG) 2227 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+1, cStartNew, cEndNew); 2228 for (p = 0; p < 4; ++p) { 2229 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 2230 } 2231 #endif 2232 /* C quad */ 2233 coneNew[0] = fStartNew + (fEnd - fStart)*2 + newpt + 3; 2234 orntNew[0] = -2; 2235 coneNew[1] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 2236 orntNew[1] = ornt[3]; 2237 coneNew[2] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2238 orntNew[2] = ornt[1] < 0 ? 0 : -2; 2239 coneNew[3] = fStartNew + (fEnd - fStart)*2 + newpt + 1; 2240 orntNew[3] = 0; 2241 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2242 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2243 #if defined(PETSC_USE_DEBUG) 2244 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+2, cStartNew, cEndNew); 2245 for (p = 0; p < 4; ++p) { 2246 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 2247 } 2248 #endif 2249 /* D quad */ 2250 coneNew[0] = fStartNew + (fEnd - fStart)*2 + newpt + 2; 2251 orntNew[0] = 0; 2252 coneNew[1] = fStartNew + (fEnd - fStart)*2 + newpt + 1; 2253 orntNew[1] = -2; 2254 coneNew[2] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2255 orntNew[2] = ornt[1] < 0 ? 0 : -2; 2256 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2257 orntNew[3] = ornt[2] < 0 ? 0 : -2; 2258 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2259 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2260 #if defined(PETSC_USE_DEBUG) 2261 if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+3, cStartNew, cEndNew); 2262 for (p = 0; p < 4; ++p) { 2263 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 2264 } 2265 #endif 2266 } 2267 /* Split faces have 2 vertices and the same cells as the parent */ 2268 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2269 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2270 for (f = fStart; f < fEnd; ++f) { 2271 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2272 2273 for (r = 0; r < 2; ++r) { 2274 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2275 const PetscInt *cone, *ornt, *support; 2276 PetscInt coneNew[2], coneSize, c, supportSize, s; 2277 2278 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2279 coneNew[0] = vStartNew + (cone[0] - vStart); 2280 coneNew[1] = vStartNew + (cone[1] - vStart); 2281 coneNew[(r+1)%2] = newv; 2282 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2283 #if defined(PETSC_USE_DEBUG) 2284 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2285 for (p = 0; p < 2; ++p) { 2286 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 2287 } 2288 #endif 2289 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2290 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2291 for (s = 0; s < supportSize; ++s) { 2292 const PetscInt p2q[4][2] = { {0, 1}, 2293 {3, 2}, 2294 {0, 3}, 2295 {1, 2} }; 2296 2297 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2298 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2299 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2300 for (c = 0; c < coneSize; ++c) { 2301 if (cone[c] == f) break; 2302 } 2303 if (coneSize == 3) supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2304 else if (coneSize == 4) supportRef[s] = cStartNew + (cMax - cStart)*3 + (support[s] - cMax)*4 + (ornt[c] < 0 ? p2q[c][(r+1)%2] : p2q[c][r]); 2305 else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone size %D", coneSize); 2306 } 2307 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2308 #if defined(PETSC_USE_DEBUG) 2309 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2310 for (p = 0; p < supportSize; ++p) { 2311 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportRef[p], cStartNew, cEndNew); 2312 } 2313 #endif 2314 } 2315 } 2316 /* Interior faces have 2 vertices and 2 cells */ 2317 for (c = cStart; c < cMax; ++c) { 2318 const PetscInt *cone; 2319 2320 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2321 for (r = 0; r < 3; ++r) { 2322 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 2323 PetscInt coneNew[2]; 2324 PetscInt supportNew[2]; 2325 2326 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2327 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2328 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2329 #if defined(PETSC_USE_DEBUG) 2330 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2331 for (p = 0; p < 2; ++p) { 2332 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 2333 } 2334 #endif 2335 supportNew[0] = (c - cStart)*3 + r%3; 2336 supportNew[1] = (c - cStart)*3 + (r+1)%3; 2337 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2338 #if defined(PETSC_USE_DEBUG) 2339 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2340 for (p = 0; p < 2; ++p) { 2341 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 2342 } 2343 #endif 2344 } 2345 } 2346 /* Hybrid interior faces have 2 vertices and 2 cells */ 2347 for (c = cMax; c < cEnd; ++c) { 2348 const PetscInt *cone; 2349 PetscInt coneNew[2], supportNew[2]; 2350 2351 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2352 for (r = 0; r < 4; ++r) { 2353 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + r; 2354 2355 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2356 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (cMax - cStart) + (c - cMax); 2357 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2358 #if defined(PETSC_USE_DEBUG) 2359 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2360 for (p = 0; p < 2; ++p) { 2361 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 2362 } 2363 #endif 2364 if (r==0) { 2365 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 0; 2366 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 1; 2367 } else if (r==1) { 2368 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 2; 2369 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 3; 2370 } else if (r==2) { 2371 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 0; 2372 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 3; 2373 } else { 2374 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 1; 2375 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 2; 2376 } 2377 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2378 #if defined(PETSC_USE_DEBUG) 2379 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2380 for (p = 0; p < 2; ++p) { 2381 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 2382 } 2383 #endif 2384 } 2385 } 2386 /* Old vertices have identical supports */ 2387 for (v = vStart; v < vEnd; ++v) { 2388 const PetscInt newp = vStartNew + (v - vStart); 2389 const PetscInt *support, *cone; 2390 PetscInt size, s; 2391 2392 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2393 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2394 for (s = 0; s < size; ++s) { 2395 PetscInt r = 0; 2396 2397 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2398 if (cone[1] == v) r = 1; 2399 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2400 } 2401 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2402 #if defined(PETSC_USE_DEBUG) 2403 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2404 for (p = 0; p < size; ++p) { 2405 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 2406 } 2407 #endif 2408 } 2409 /* Split-face vertices have cells + 2 supports */ 2410 for (f = fStart; f < fEnd; ++f) { 2411 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2412 const PetscInt *cone, *support; 2413 PetscInt size, s; 2414 2415 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2416 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2417 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2418 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2419 for (s = 0; s < size; ++s) { 2420 PetscInt r = 0, coneSize; 2421 2422 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2423 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2424 if (coneSize == 3) { 2425 if (cone[1] == f) r = 1; 2426 else if (cone[2] == f) r = 2; 2427 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 2428 } else if (coneSize == 4) { 2429 if (cone[1] == f) r = 1; 2430 else if (cone[2] == f) r = 2; 2431 else if (cone[3] == f) r = 3; 2432 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (support[s] - cMax)*4 + r; 2433 } else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone size %D", coneSize); 2434 } 2435 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2436 #if defined(PETSC_USE_DEBUG) 2437 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2438 for (p = 0; p < 2+size; ++p) { 2439 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 2440 } 2441 #endif 2442 } 2443 /* Interior vertices have 3 supports */ 2444 for (c = cStart; c < cMax; ++c) { 2445 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 2446 2447 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2448 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2449 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2450 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2451 } 2452 /* Hybrid interior vertices have 4 supports */ 2453 for (c = cMax; c < cEnd; ++c) { 2454 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 2455 2456 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 0; 2457 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 1; 2458 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 2; 2459 supportRef[3] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 3; 2460 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2461 } 2462 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2463 break; 2464 case REFINER_HEX_2D: 2465 /* 2466 3---------2---------2 2467 | | | 2468 | D 2 C | 2469 | | | 2470 3----3----0----1----1 2471 | | | 2472 | A 0 B | 2473 | | | 2474 0---------0---------1 2475 */ 2476 /* All cells have 4 faces */ 2477 for (c = cStart; c < cEnd; ++c) { 2478 const PetscInt newp = (c - cStart)*4; 2479 const PetscInt *cone, *ornt; 2480 PetscInt coneNew[4], orntNew[4]; 2481 2482 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2483 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2484 /* A quad */ 2485 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2486 orntNew[0] = ornt[0]; 2487 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 2488 orntNew[1] = 0; 2489 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 2490 orntNew[2] = -2; 2491 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 2492 orntNew[3] = ornt[3]; 2493 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2494 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2495 #if defined(PETSC_USE_DEBUG) 2496 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+0, cStartNew, cEndNew); 2497 for (p = 0; p < 4; ++p) { 2498 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 2499 } 2500 #endif 2501 /* B quad */ 2502 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2503 orntNew[0] = ornt[0]; 2504 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2505 orntNew[1] = ornt[1]; 2506 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 2507 orntNew[2] = -2; 2508 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 2509 orntNew[3] = -2; 2510 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2511 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2512 #if defined(PETSC_USE_DEBUG) 2513 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+1, cStartNew, cEndNew); 2514 for (p = 0; p < 4; ++p) { 2515 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 2516 } 2517 #endif 2518 /* C quad */ 2519 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 2520 orntNew[0] = 0; 2521 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2522 orntNew[1] = ornt[1]; 2523 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2524 orntNew[2] = ornt[2]; 2525 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 2526 orntNew[3] = -2; 2527 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2528 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2529 #if defined(PETSC_USE_DEBUG) 2530 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+2, cStartNew, cEndNew); 2531 for (p = 0; p < 4; ++p) { 2532 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 2533 } 2534 #endif 2535 /* D quad */ 2536 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 2537 orntNew[0] = 0; 2538 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 2539 orntNew[1] = 0; 2540 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2541 orntNew[2] = ornt[2]; 2542 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 2543 orntNew[3] = ornt[3]; 2544 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2545 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2546 #if defined(PETSC_USE_DEBUG) 2547 if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+3, cStartNew, cEndNew); 2548 for (p = 0; p < 4; ++p) { 2549 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 2550 } 2551 #endif 2552 } 2553 /* Split faces have 2 vertices and the same cells as the parent */ 2554 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2555 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2556 for (f = fStart; f < fEnd; ++f) { 2557 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2558 2559 for (r = 0; r < 2; ++r) { 2560 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2561 const PetscInt *cone, *ornt, *support; 2562 PetscInt coneNew[2], coneSize, c, supportSize, s; 2563 2564 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2565 coneNew[0] = vStartNew + (cone[0] - vStart); 2566 coneNew[1] = vStartNew + (cone[1] - vStart); 2567 coneNew[(r+1)%2] = newv; 2568 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2569 #if defined(PETSC_USE_DEBUG) 2570 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2571 for (p = 0; p < 2; ++p) { 2572 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 2573 } 2574 #endif 2575 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2576 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2577 for (s = 0; s < supportSize; ++s) { 2578 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2579 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2580 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2581 for (c = 0; c < coneSize; ++c) { 2582 if (cone[c] == f) break; 2583 } 2584 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 2585 } 2586 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2587 #if defined(PETSC_USE_DEBUG) 2588 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2589 for (p = 0; p < supportSize; ++p) { 2590 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportRef[p], cStartNew, cEndNew); 2591 } 2592 #endif 2593 } 2594 } 2595 /* Interior faces have 2 vertices and 2 cells */ 2596 for (c = cStart; c < cEnd; ++c) { 2597 const PetscInt *cone; 2598 PetscInt coneNew[2], supportNew[2]; 2599 2600 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2601 for (r = 0; r < 4; ++r) { 2602 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 2603 2604 if (r==1 || r==2) { 2605 coneNew[0] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2606 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2607 } else { 2608 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2609 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2610 } 2611 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2612 #if defined(PETSC_USE_DEBUG) 2613 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2614 for (p = 0; p < 2; ++p) { 2615 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 2616 } 2617 #endif 2618 supportNew[0] = (c - cStart)*4 + r; 2619 supportNew[1] = (c - cStart)*4 + (r+1)%4; 2620 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2621 #if defined(PETSC_USE_DEBUG) 2622 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2623 for (p = 0; p < 2; ++p) { 2624 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 2625 } 2626 #endif 2627 } 2628 } 2629 /* Old vertices have identical supports */ 2630 for (v = vStart; v < vEnd; ++v) { 2631 const PetscInt newp = vStartNew + (v - vStart); 2632 const PetscInt *support, *cone; 2633 PetscInt size, s; 2634 2635 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2636 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2637 for (s = 0; s < size; ++s) { 2638 PetscInt r = 0; 2639 2640 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2641 if (cone[1] == v) r = 1; 2642 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2643 } 2644 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2645 #if defined(PETSC_USE_DEBUG) 2646 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2647 for (p = 0; p < size; ++p) { 2648 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 2649 } 2650 #endif 2651 } 2652 /* Face vertices have 2 + cells supports */ 2653 for (f = fStart; f < fEnd; ++f) { 2654 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2655 const PetscInt *cone, *support; 2656 PetscInt size, s; 2657 2658 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2659 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2660 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2661 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2662 for (s = 0; s < size; ++s) { 2663 PetscInt r = 0; 2664 2665 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2666 if (cone[1] == f) r = 1; 2667 else if (cone[2] == f) r = 2; 2668 else if (cone[3] == f) r = 3; 2669 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r; 2670 } 2671 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2672 #if defined(PETSC_USE_DEBUG) 2673 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2674 for (p = 0; p < 2+size; ++p) { 2675 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 2676 } 2677 #endif 2678 } 2679 /* Cell vertices have 4 supports */ 2680 for (c = cStart; c < cEnd; ++c) { 2681 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2682 PetscInt supportNew[4]; 2683 2684 for (r = 0; r < 4; ++r) { 2685 supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 2686 } 2687 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2688 } 2689 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2690 break; 2691 case REFINER_HYBRID_SIMPLEX_2D: 2692 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 2693 cMax = PetscMin(cEnd, cMax); 2694 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 2695 fMax = PetscMin(fEnd, fMax); 2696 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 2697 /* Interior cells have 3 faces */ 2698 for (c = cStart; c < cMax; ++c) { 2699 const PetscInt newp = cStartNew + (c - cStart)*4; 2700 const PetscInt *cone, *ornt; 2701 PetscInt coneNew[3], orntNew[3]; 2702 2703 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2704 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2705 /* A triangle */ 2706 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2707 orntNew[0] = ornt[0]; 2708 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 2709 orntNew[1] = -2; 2710 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2711 orntNew[2] = ornt[2]; 2712 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2713 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2714 #if defined(PETSC_USE_DEBUG) 2715 if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an interior cell [%D, %D)", newp+0, cStartNew, cMaxNew); 2716 for (p = 0; p < 3; ++p) { 2717 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an interior face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 2718 } 2719 #endif 2720 /* B triangle */ 2721 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2722 orntNew[0] = ornt[0]; 2723 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2724 orntNew[1] = ornt[1]; 2725 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 2726 orntNew[2] = -2; 2727 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2728 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2729 #if defined(PETSC_USE_DEBUG) 2730 if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an interior cell [%D, %D)", newp+1, cStartNew, cMaxNew); 2731 for (p = 0; p < 3; ++p) { 2732 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an interior face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 2733 } 2734 #endif 2735 /* C triangle */ 2736 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 2737 orntNew[0] = -2; 2738 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2739 orntNew[1] = ornt[1]; 2740 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2741 orntNew[2] = ornt[2]; 2742 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2743 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2744 #if defined(PETSC_USE_DEBUG) 2745 if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an interior cell [%D, %D)", newp+2, cStartNew, cMaxNew); 2746 for (p = 0; p < 3; ++p) { 2747 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an interior face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 2748 } 2749 #endif 2750 /* D triangle */ 2751 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 2752 orntNew[0] = 0; 2753 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 2754 orntNew[1] = 0; 2755 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 2756 orntNew[2] = 0; 2757 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2758 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2759 #if defined(PETSC_USE_DEBUG) 2760 if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an interior cell [%D, %D)", newp+3, cStartNew, cMaxNew); 2761 for (p = 0; p < 3; ++p) { 2762 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an interior face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 2763 } 2764 #endif 2765 } 2766 /* 2767 2----3----3 2768 | | 2769 | B | 2770 | | 2771 0----4--- 1 2772 | | 2773 | A | 2774 | | 2775 0----2----1 2776 */ 2777 /* Hybrid cells have 4 faces */ 2778 for (c = cMax; c < cEnd; ++c) { 2779 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 2780 const PetscInt *cone, *ornt; 2781 PetscInt coneNew[4], orntNew[4], r; 2782 2783 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2784 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2785 r = (ornt[0] < 0 ? 1 : 0); 2786 /* A quad */ 2787 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + r; 2788 orntNew[0] = ornt[0]; 2789 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + r; 2790 orntNew[1] = ornt[1]; 2791 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax); 2792 orntNew[2+r] = 0; 2793 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2794 orntNew[3-r] = 0; 2795 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2796 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2797 #if defined(PETSC_USE_DEBUG) 2798 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+0, cStartNew, cEndNew); 2799 for (p = 0; p < 4; ++p) { 2800 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 2801 } 2802 #endif 2803 /* B quad */ 2804 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + 1-r; 2805 orntNew[0] = ornt[0]; 2806 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + 1-r; 2807 orntNew[1] = ornt[1]; 2808 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2809 orntNew[2+r] = 0; 2810 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax); 2811 orntNew[3-r] = 0; 2812 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2813 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2814 #if defined(PETSC_USE_DEBUG) 2815 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+1, cStartNew, cEndNew); 2816 for (p = 0; p < 4; ++p) { 2817 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 2818 } 2819 #endif 2820 } 2821 /* Interior split faces have 2 vertices and the same cells as the parent */ 2822 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2823 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2824 for (f = fStart; f < fMax; ++f) { 2825 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2826 2827 for (r = 0; r < 2; ++r) { 2828 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2829 const PetscInt *cone, *ornt, *support; 2830 PetscInt coneNew[2], coneSize, c, supportSize, s; 2831 2832 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2833 coneNew[0] = vStartNew + (cone[0] - vStart); 2834 coneNew[1] = vStartNew + (cone[1] - vStart); 2835 coneNew[(r+1)%2] = newv; 2836 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2837 #if defined(PETSC_USE_DEBUG) 2838 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2839 for (p = 0; p < 2; ++p) { 2840 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 2841 } 2842 #endif 2843 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2844 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2845 for (s = 0; s < supportSize; ++s) { 2846 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2847 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2848 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2849 for (c = 0; c < coneSize; ++c) if (cone[c] == f) break; 2850 if (support[s] >= cMax) { 2851 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r); 2852 } else { 2853 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2854 } 2855 } 2856 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2857 #if defined(PETSC_USE_DEBUG) 2858 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2859 for (p = 0; p < supportSize; ++p) { 2860 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportRef[p], cStartNew, cEndNew); 2861 } 2862 #endif 2863 } 2864 } 2865 /* Interior cell faces have 2 vertices and 2 cells */ 2866 for (c = cStart; c < cMax; ++c) { 2867 const PetscInt *cone; 2868 2869 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2870 for (r = 0; r < 3; ++r) { 2871 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 2872 PetscInt coneNew[2]; 2873 PetscInt supportNew[2]; 2874 2875 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2876 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 2877 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2878 #if defined(PETSC_USE_DEBUG) 2879 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2880 for (p = 0; p < 2; ++p) { 2881 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 2882 } 2883 #endif 2884 supportNew[0] = (c - cStart)*4 + (r+1)%3; 2885 supportNew[1] = (c - cStart)*4 + 3; 2886 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2887 #if defined(PETSC_USE_DEBUG) 2888 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2889 for (p = 0; p < 2; ++p) { 2890 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 2891 } 2892 #endif 2893 } 2894 } 2895 /* Interior hybrid faces have 2 vertices and the same cells */ 2896 for (f = fMax; f < fEnd; ++f) { 2897 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 2898 const PetscInt *cone, *ornt; 2899 const PetscInt *support; 2900 PetscInt coneNew[2]; 2901 PetscInt supportNew[2]; 2902 PetscInt size, s, r; 2903 2904 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2905 coneNew[0] = vStartNew + (cone[0] - vStart); 2906 coneNew[1] = vStartNew + (cone[1] - vStart); 2907 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2908 #if defined(PETSC_USE_DEBUG) 2909 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2910 for (p = 0; p < 2; ++p) { 2911 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 2912 } 2913 #endif 2914 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2915 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2916 for (s = 0; s < size; ++s) { 2917 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2918 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2919 for (r = 0; r < 2; ++r) { 2920 if (cone[r+2] == f) break; 2921 } 2922 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r); 2923 } 2924 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2925 #if defined(PETSC_USE_DEBUG) 2926 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2927 for (p = 0; p < size; ++p) { 2928 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 2929 } 2930 #endif 2931 } 2932 /* Cell hybrid faces have 2 vertices and 2 cells */ 2933 for (c = cMax; c < cEnd; ++c) { 2934 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2935 const PetscInt *cone; 2936 PetscInt coneNew[2]; 2937 PetscInt supportNew[2]; 2938 2939 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2940 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 2941 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 2942 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2943 #if defined(PETSC_USE_DEBUG) 2944 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2945 for (p = 0; p < 2; ++p) { 2946 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 2947 } 2948 #endif 2949 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 2950 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 2951 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2952 #if defined(PETSC_USE_DEBUG) 2953 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2954 for (p = 0; p < 2; ++p) { 2955 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 2956 } 2957 #endif 2958 } 2959 /* Old vertices have identical supports */ 2960 for (v = vStart; v < vEnd; ++v) { 2961 const PetscInt newp = vStartNew + (v - vStart); 2962 const PetscInt *support, *cone; 2963 PetscInt size, s; 2964 2965 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2966 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2967 for (s = 0; s < size; ++s) { 2968 if (support[s] >= fMax) { 2969 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax); 2970 } else { 2971 PetscInt r = 0; 2972 2973 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2974 if (cone[1] == v) r = 1; 2975 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2976 } 2977 } 2978 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2979 #if defined(PETSC_USE_DEBUG) 2980 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2981 for (p = 0; p < size; ++p) { 2982 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 2983 } 2984 #endif 2985 } 2986 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 2987 for (f = fStart; f < fMax; ++f) { 2988 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2989 const PetscInt *cone, *support; 2990 PetscInt size, newSize = 2, s; 2991 2992 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2993 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2994 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2995 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2996 for (s = 0; s < size; ++s) { 2997 PetscInt r = 0; 2998 2999 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3000 if (support[s] >= cMax) { 3001 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax); 3002 3003 newSize += 1; 3004 } else { 3005 if (cone[1] == f) r = 1; 3006 else if (cone[2] == f) r = 2; 3007 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 3008 supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r; 3009 3010 newSize += 2; 3011 } 3012 } 3013 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3014 #if defined(PETSC_USE_DEBUG) 3015 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3016 for (p = 0; p < newSize; ++p) { 3017 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 3018 } 3019 #endif 3020 } 3021 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3022 break; 3023 case REFINER_HYBRID_HEX_2D: 3024 /* Hybrid Hex 2D */ 3025 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 3026 cMax = PetscMin(cEnd, cMax); 3027 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 3028 fMax = PetscMin(fEnd, fMax); 3029 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 3030 /* Interior cells have 4 faces */ 3031 for (c = cStart; c < cMax; ++c) { 3032 const PetscInt newp = cStartNew + (c - cStart)*4; 3033 const PetscInt *cone, *ornt; 3034 PetscInt coneNew[4], orntNew[4]; 3035 3036 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3037 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3038 /* A quad */ 3039 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 3040 orntNew[0] = ornt[0]; 3041 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 3042 orntNew[1] = 0; 3043 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 3044 orntNew[2] = -2; 3045 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 3046 orntNew[3] = ornt[3]; 3047 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3048 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3049 #if defined(PETSC_USE_DEBUG) 3050 if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an interior cell [%D, %D)", newp+0, cStartNew, cMaxNew); 3051 for (p = 0; p < 4; ++p) { 3052 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an interior face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 3053 } 3054 #endif 3055 /* B quad */ 3056 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 3057 orntNew[0] = ornt[0]; 3058 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 3059 orntNew[1] = ornt[1]; 3060 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 3061 orntNew[2] = 0; 3062 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 3063 orntNew[3] = -2; 3064 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3065 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3066 #if defined(PETSC_USE_DEBUG) 3067 if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an interior cell [%D, %D)", newp+1, cStartNew, cMaxNew); 3068 for (p = 0; p < 4; ++p) { 3069 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an interior face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 3070 } 3071 #endif 3072 /* C quad */ 3073 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 3074 orntNew[0] = -2; 3075 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 3076 orntNew[1] = ornt[1]; 3077 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 3078 orntNew[2] = ornt[2]; 3079 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 3080 orntNew[3] = 0; 3081 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3082 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3083 #if defined(PETSC_USE_DEBUG) 3084 if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an interior cell [%D, %D)", newp+2, cStartNew, cMaxNew); 3085 for (p = 0; p < 4; ++p) { 3086 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an interior face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 3087 } 3088 #endif 3089 /* D quad */ 3090 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 3091 orntNew[0] = 0; 3092 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 3093 orntNew[1] = -2; 3094 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 3095 orntNew[2] = ornt[2]; 3096 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 3097 orntNew[3] = ornt[3]; 3098 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3099 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3100 #if defined(PETSC_USE_DEBUG) 3101 if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an interior cell [%D, %D)", newp+3, cStartNew, cMaxNew); 3102 for (p = 0; p < 4; ++p) { 3103 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an interior face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 3104 } 3105 #endif 3106 } 3107 /* 3108 2----3----3 3109 | | 3110 | B | 3111 | | 3112 0----4--- 1 3113 | | 3114 | A | 3115 | | 3116 0----2----1 3117 */ 3118 /* Hybrid cells have 4 faces */ 3119 for (c = cMax; c < cEnd; ++c) { 3120 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 3121 const PetscInt *cone, *ornt; 3122 PetscInt coneNew[4], orntNew[4]; 3123 3124 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3125 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3126 /* A quad */ 3127 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 3128 orntNew[0] = ornt[0]; 3129 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 3130 orntNew[1] = ornt[1]; 3131 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax); 3132 orntNew[2] = 0; 3133 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 3134 orntNew[3] = 0; 3135 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3136 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3137 #if defined(PETSC_USE_DEBUG) 3138 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+0, cStartNew, cEndNew); 3139 for (p = 0; p < 4; ++p) { 3140 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 3141 } 3142 #endif 3143 /* B quad */ 3144 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 3145 orntNew[0] = ornt[0]; 3146 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 3147 orntNew[1] = ornt[1]; 3148 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 3149 orntNew[2] = 0; 3150 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax); 3151 orntNew[3] = 0; 3152 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3153 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3154 #if defined(PETSC_USE_DEBUG) 3155 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+1, cStartNew, cEndNew); 3156 for (p = 0; p < 4; ++p) { 3157 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 3158 } 3159 #endif 3160 } 3161 /* Interior split faces have 2 vertices and the same cells as the parent */ 3162 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3163 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 3164 for (f = fStart; f < fMax; ++f) { 3165 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 3166 3167 for (r = 0; r < 2; ++r) { 3168 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 3169 const PetscInt *cone, *ornt, *support; 3170 PetscInt coneNew[2], coneSize, c, supportSize, s; 3171 3172 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3173 coneNew[0] = vStartNew + (cone[0] - vStart); 3174 coneNew[1] = vStartNew + (cone[1] - vStart); 3175 coneNew[(r+1)%2] = newv; 3176 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3177 #if defined(PETSC_USE_DEBUG) 3178 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3179 for (p = 0; p < 2; ++p) { 3180 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 3181 } 3182 #endif 3183 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3184 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3185 for (s = 0; s < supportSize; ++s) { 3186 if (support[s] >= cMax) { 3187 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 3188 } else { 3189 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3190 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3191 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3192 for (c = 0; c < coneSize; ++c) { 3193 if (cone[c] == f) break; 3194 } 3195 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 3196 } 3197 } 3198 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3199 #if defined(PETSC_USE_DEBUG) 3200 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3201 for (p = 0; p < supportSize; ++p) { 3202 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportRef[p], cStartNew, cEndNew); 3203 } 3204 #endif 3205 } 3206 } 3207 /* Interior cell faces have 2 vertices and 2 cells */ 3208 for (c = cStart; c < cMax; ++c) { 3209 const PetscInt *cone; 3210 3211 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3212 for (r = 0; r < 4; ++r) { 3213 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 3214 PetscInt coneNew[2], supportNew[2]; 3215 3216 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 3217 coneNew[1] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 3218 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3219 #if defined(PETSC_USE_DEBUG) 3220 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3221 for (p = 0; p < 2; ++p) { 3222 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 3223 } 3224 #endif 3225 supportNew[0] = (c - cStart)*4 + r; 3226 supportNew[1] = (c - cStart)*4 + (r+1)%4; 3227 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3228 #if defined(PETSC_USE_DEBUG) 3229 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3230 for (p = 0; p < 2; ++p) { 3231 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 3232 } 3233 #endif 3234 } 3235 } 3236 /* Hybrid faces have 2 vertices and the same cells */ 3237 for (f = fMax; f < fEnd; ++f) { 3238 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 3239 const PetscInt *cone, *support; 3240 PetscInt coneNew[2], supportNew[2]; 3241 PetscInt size, s, r; 3242 3243 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3244 coneNew[0] = vStartNew + (cone[0] - vStart); 3245 coneNew[1] = vStartNew + (cone[1] - vStart); 3246 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3247 #if defined(PETSC_USE_DEBUG) 3248 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3249 for (p = 0; p < 2; ++p) { 3250 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 3251 } 3252 #endif 3253 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3254 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3255 for (s = 0; s < size; ++s) { 3256 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3257 for (r = 0; r < 2; ++r) { 3258 if (cone[r+2] == f) break; 3259 } 3260 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 3261 } 3262 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3263 #if defined(PETSC_USE_DEBUG) 3264 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3265 for (p = 0; p < size; ++p) { 3266 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 3267 } 3268 #endif 3269 } 3270 /* Cell hybrid faces have 2 vertices and 2 cells */ 3271 for (c = cMax; c < cEnd; ++c) { 3272 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 3273 const PetscInt *cone; 3274 PetscInt coneNew[2], supportNew[2]; 3275 3276 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3277 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 3278 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 3279 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3280 #if defined(PETSC_USE_DEBUG) 3281 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3282 for (p = 0; p < 2; ++p) { 3283 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 3284 } 3285 #endif 3286 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 3287 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 3288 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3289 #if defined(PETSC_USE_DEBUG) 3290 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3291 for (p = 0; p < 2; ++p) { 3292 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 3293 } 3294 #endif 3295 } 3296 /* Old vertices have identical supports */ 3297 for (v = vStart; v < vEnd; ++v) { 3298 const PetscInt newp = vStartNew + (v - vStart); 3299 const PetscInt *support, *cone; 3300 PetscInt size, s; 3301 3302 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3303 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3304 for (s = 0; s < size; ++s) { 3305 if (support[s] >= fMax) { 3306 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax); 3307 } else { 3308 PetscInt r = 0; 3309 3310 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3311 if (cone[1] == v) r = 1; 3312 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 3313 } 3314 } 3315 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3316 #if defined(PETSC_USE_DEBUG) 3317 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3318 for (p = 0; p < size; ++p) { 3319 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 3320 } 3321 #endif 3322 } 3323 /* Face vertices have 2 + cells supports */ 3324 for (f = fStart; f < fMax; ++f) { 3325 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 3326 const PetscInt *cone, *support; 3327 PetscInt size, s; 3328 3329 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3330 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3331 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 3332 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 3333 for (s = 0; s < size; ++s) { 3334 PetscInt r = 0; 3335 3336 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3337 if (support[s] >= cMax) { 3338 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax); 3339 } else { 3340 if (cone[1] == f) r = 1; 3341 else if (cone[2] == f) r = 2; 3342 else if (cone[3] == f) r = 3; 3343 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r; 3344 } 3345 } 3346 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3347 #if defined(PETSC_USE_DEBUG) 3348 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3349 for (p = 0; p < 2+size; ++p) { 3350 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 3351 } 3352 #endif 3353 } 3354 /* Cell vertices have 4 supports */ 3355 for (c = cStart; c < cMax; ++c) { 3356 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 3357 PetscInt supportNew[4]; 3358 3359 for (r = 0; r < 4; ++r) { 3360 supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 3361 } 3362 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3363 } 3364 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3365 break; 3366 case REFINER_SIMPLEX_3D: 3367 /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 3368 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 3369 for (c = cStart; c < cEnd; ++c) { 3370 const PetscInt newp = cStartNew + (c - cStart)*8; 3371 const PetscInt *cone, *ornt; 3372 PetscInt coneNew[4], orntNew[4]; 3373 3374 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3375 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3376 /* A tetrahedron: {0, a, c, d} */ 3377 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 3378 orntNew[0] = ornt[0]; 3379 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 3380 orntNew[1] = ornt[1]; 3381 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 3382 orntNew[2] = ornt[2]; 3383 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 3384 orntNew[3] = 0; 3385 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3386 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3387 #if defined(PETSC_USE_DEBUG) 3388 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+0, cStartNew, cEndNew); 3389 for (p = 0; p < 4; ++p) { 3390 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 3391 } 3392 #endif 3393 /* B tetrahedron: {a, 1, b, e} */ 3394 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 3395 orntNew[0] = ornt[0]; 3396 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 3397 orntNew[1] = ornt[1]; 3398 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 3399 orntNew[2] = 0; 3400 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 3401 orntNew[3] = ornt[3]; 3402 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3403 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3404 #if defined(PETSC_USE_DEBUG) 3405 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+1, cStartNew, cEndNew); 3406 for (p = 0; p < 4; ++p) { 3407 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 3408 } 3409 #endif 3410 /* C tetrahedron: {c, b, 2, f} */ 3411 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 3412 orntNew[0] = ornt[0]; 3413 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 3414 orntNew[1] = 0; 3415 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 3416 orntNew[2] = ornt[2]; 3417 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 3418 orntNew[3] = ornt[3]; 3419 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3420 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3421 #if defined(PETSC_USE_DEBUG) 3422 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+2, cStartNew, cEndNew); 3423 for (p = 0; p < 4; ++p) { 3424 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 3425 } 3426 #endif 3427 /* D tetrahedron: {d, e, f, 3} */ 3428 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 3429 orntNew[0] = 0; 3430 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 3431 orntNew[1] = ornt[1]; 3432 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 3433 orntNew[2] = ornt[2]; 3434 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 3435 orntNew[3] = ornt[3]; 3436 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3437 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3438 #if defined(PETSC_USE_DEBUG) 3439 if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+3, cStartNew, cEndNew); 3440 for (p = 0; p < 4; ++p) { 3441 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 3442 } 3443 #endif 3444 /* A' tetrahedron: {c, d, a, f} */ 3445 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 3446 orntNew[0] = -3; 3447 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 3448 orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0); 3449 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 3450 orntNew[2] = 0; 3451 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 3452 orntNew[3] = 2; 3453 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3454 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3455 #if defined(PETSC_USE_DEBUG) 3456 if ((newp+4 < cStartNew) || (newp+4 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+4, cStartNew, cEndNew); 3457 for (p = 0; p < 4; ++p) { 3458 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 3459 } 3460 #endif 3461 /* B' tetrahedron: {e, b, a, f} */ 3462 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 3463 orntNew[0] = -2; 3464 coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3; 3465 orntNew[1] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 1)+1) : GetTriMidEdge_Static(ornt[3], 1); 3466 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 3467 orntNew[2] = 0; 3468 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 3469 orntNew[3] = 0; 3470 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3471 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3472 #if defined(PETSC_USE_DEBUG) 3473 if ((newp+5 < cStartNew) || (newp+5 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+5, cStartNew, cEndNew); 3474 for (p = 0; p < 4; ++p) { 3475 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 3476 } 3477 #endif 3478 /* C' tetrahedron: {f, a, c, b} */ 3479 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 3480 orntNew[0] = -2; 3481 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 3482 orntNew[1] = -2; 3483 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 3484 orntNew[2] = -1; 3485 coneNew[3] = fStartNew + (cone[0] - fStart)*4 + 3; 3486 orntNew[3] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2); 3487 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3488 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3489 #if defined(PETSC_USE_DEBUG) 3490 if ((newp+6 < cStartNew) || (newp+6 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+6, cStartNew, cEndNew); 3491 for (p = 0; p < 4; ++p) { 3492 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 3493 } 3494 #endif 3495 /* D' tetrahedron: {f, a, e, d} */ 3496 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 3497 orntNew[0] = -2; 3498 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 3499 orntNew[1] = -1; 3500 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 3501 orntNew[2] = -2; 3502 coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3; 3503 orntNew[3] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 1)+1) : GetTriMidEdge_Static(ornt[1], 1); 3504 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3505 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3506 #if defined(PETSC_USE_DEBUG) 3507 if ((newp+7 < cStartNew) || (newp+7 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+7, cStartNew, cEndNew); 3508 for (p = 0; p < 4; ++p) { 3509 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 3510 } 3511 #endif 3512 } 3513 /* Split faces have 3 edges and the same cells as the parent */ 3514 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3515 ierr = PetscMalloc1(2 + maxSupportSize*3, &supportRef);CHKERRQ(ierr); 3516 for (f = fStart; f < fEnd; ++f) { 3517 const PetscInt newp = fStartNew + (f - fStart)*4; 3518 const PetscInt *cone, *ornt, *support; 3519 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 3520 3521 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3522 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3523 /* A triangle */ 3524 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 3525 orntNew[0] = ornt[0]; 3526 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 3527 orntNew[1] = -2; 3528 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 3529 orntNew[2] = ornt[2]; 3530 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3531 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3532 #if defined(PETSC_USE_DEBUG) 3533 if ((newp+0 < fStartNew) || (newp+0 >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp+0, fStartNew, fEndNew); 3534 for (p = 0; p < 3; ++p) { 3535 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 3536 } 3537 #endif 3538 /* B triangle */ 3539 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 3540 orntNew[0] = ornt[0]; 3541 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 3542 orntNew[1] = ornt[1]; 3543 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 3544 orntNew[2] = -2; 3545 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3546 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3547 #if defined(PETSC_USE_DEBUG) 3548 if ((newp+1 < fStartNew) || (newp+1 >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp+1, fStartNew, fEndNew); 3549 for (p = 0; p < 3; ++p) { 3550 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 3551 } 3552 #endif 3553 /* C triangle */ 3554 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 3555 orntNew[0] = -2; 3556 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 3557 orntNew[1] = ornt[1]; 3558 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 3559 orntNew[2] = ornt[2]; 3560 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3561 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3562 #if defined(PETSC_USE_DEBUG) 3563 if ((newp+2 < fStartNew) || (newp+2 >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp+2, fStartNew, fEndNew); 3564 for (p = 0; p < 3; ++p) { 3565 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 3566 } 3567 #endif 3568 /* D triangle */ 3569 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 3570 orntNew[0] = 0; 3571 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 3572 orntNew[1] = 0; 3573 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 3574 orntNew[2] = 0; 3575 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3576 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3577 #if defined(PETSC_USE_DEBUG) 3578 if ((newp+3 < fStartNew) || (newp+3 >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp+3, fStartNew, fEndNew); 3579 for (p = 0; p < 3; ++p) { 3580 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 3581 } 3582 #endif 3583 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3584 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3585 for (r = 0; r < 4; ++r) { 3586 for (s = 0; s < supportSize; ++s) { 3587 PetscInt subf; 3588 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3589 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3590 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3591 for (c = 0; c < coneSize; ++c) { 3592 if (cone[c] == f) break; 3593 } 3594 subf = GetTriSubfaceInverse_Static(ornt[c], r); 3595 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 3596 } 3597 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 3598 #if defined(PETSC_USE_DEBUG) 3599 if ((newp+r < fStartNew) || (newp+r >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp+r, fStartNew, fEndNew); 3600 for (p = 0; p < supportSize; ++p) { 3601 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportRef[p], cStartNew, cEndNew); 3602 } 3603 #endif 3604 } 3605 } 3606 /* Interior faces have 3 edges and 2 cells */ 3607 for (c = cStart; c < cEnd; ++c) { 3608 PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 3609 const PetscInt *cone, *ornt; 3610 PetscInt coneNew[3], orntNew[3]; 3611 PetscInt supportNew[2]; 3612 3613 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3614 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3615 /* Face A: {c, a, d} */ 3616 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3617 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3618 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3619 orntNew[1] = ornt[1] < 0 ? -2 : 0; 3620 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2); 3621 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3622 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3623 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3624 #if defined(PETSC_USE_DEBUG) 3625 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3626 for (p = 0; p < 3; ++p) { 3627 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 3628 } 3629 #endif 3630 supportNew[0] = (c - cStart)*8 + 0; 3631 supportNew[1] = (c - cStart)*8 + 0+4; 3632 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3633 #if defined(PETSC_USE_DEBUG) 3634 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3635 for (p = 0; p < 2; ++p) { 3636 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 3637 } 3638 #endif 3639 ++newp; 3640 /* Face B: {a, b, e} */ 3641 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3642 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3643 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0); 3644 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3645 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3646 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3647 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3648 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3649 #if defined(PETSC_USE_DEBUG) 3650 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3651 for (p = 0; p < 3; ++p) { 3652 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 3653 } 3654 #endif 3655 supportNew[0] = (c - cStart)*8 + 1; 3656 supportNew[1] = (c - cStart)*8 + 1+4; 3657 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3658 #if defined(PETSC_USE_DEBUG) 3659 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3660 for (p = 0; p < 2; ++p) { 3661 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 3662 } 3663 #endif 3664 ++newp; 3665 /* Face C: {c, f, b} */ 3666 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3667 orntNew[0] = ornt[2] < 0 ? -2 : 0; 3668 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3669 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3670 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1); 3671 orntNew[2] = ornt[0] < 0 ? -2 : 0; 3672 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3673 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3674 #if defined(PETSC_USE_DEBUG) 3675 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3676 for (p = 0; p < 3; ++p) { 3677 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 3678 } 3679 #endif 3680 supportNew[0] = (c - cStart)*8 + 2; 3681 supportNew[1] = (c - cStart)*8 + 2+4; 3682 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3683 #if defined(PETSC_USE_DEBUG) 3684 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3685 for (p = 0; p < 2; ++p) { 3686 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 3687 } 3688 #endif 3689 ++newp; 3690 /* Face D: {d, e, f} */ 3691 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0); 3692 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3693 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3694 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3695 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3696 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3697 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3698 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3699 #if defined(PETSC_USE_DEBUG) 3700 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3701 for (p = 0; p < 3; ++p) { 3702 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 3703 } 3704 #endif 3705 supportNew[0] = (c - cStart)*8 + 3; 3706 supportNew[1] = (c - cStart)*8 + 3+4; 3707 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3708 #if defined(PETSC_USE_DEBUG) 3709 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3710 for (p = 0; p < 2; ++p) { 3711 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 3712 } 3713 #endif 3714 ++newp; 3715 /* Face E: {d, f, a} */ 3716 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3717 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3718 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3719 orntNew[1] = -2; 3720 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3721 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3722 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3723 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3724 #if defined(PETSC_USE_DEBUG) 3725 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3726 for (p = 0; p < 3; ++p) { 3727 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 3728 } 3729 #endif 3730 supportNew[0] = (c - cStart)*8 + 0+4; 3731 supportNew[1] = (c - cStart)*8 + 3+4; 3732 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3733 #if defined(PETSC_USE_DEBUG) 3734 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3735 for (p = 0; p < 2; ++p) { 3736 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 3737 } 3738 #endif 3739 ++newp; 3740 /* Face F: {c, a, f} */ 3741 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3742 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3743 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3744 orntNew[1] = 0; 3745 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3746 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3747 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3748 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3749 #if defined(PETSC_USE_DEBUG) 3750 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3751 for (p = 0; p < 3; ++p) { 3752 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 3753 } 3754 #endif 3755 supportNew[0] = (c - cStart)*8 + 0+4; 3756 supportNew[1] = (c - cStart)*8 + 2+4; 3757 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3758 #if defined(PETSC_USE_DEBUG) 3759 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3760 for (p = 0; p < 2; ++p) { 3761 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 3762 } 3763 #endif 3764 ++newp; 3765 /* Face G: {e, a, f} */ 3766 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3767 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3768 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3769 orntNew[1] = 0; 3770 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3771 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3772 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3773 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3774 #if defined(PETSC_USE_DEBUG) 3775 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3776 for (p = 0; p < 3; ++p) { 3777 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 3778 } 3779 #endif 3780 supportNew[0] = (c - cStart)*8 + 1+4; 3781 supportNew[1] = (c - cStart)*8 + 3+4; 3782 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3783 #if defined(PETSC_USE_DEBUG) 3784 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3785 for (p = 0; p < 2; ++p) { 3786 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 3787 } 3788 #endif 3789 ++newp; 3790 /* Face H: {a, b, f} */ 3791 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3792 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3793 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3794 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3795 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3796 orntNew[2] = -2; 3797 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3798 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3799 #if defined(PETSC_USE_DEBUG) 3800 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3801 for (p = 0; p < 3; ++p) { 3802 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 3803 } 3804 #endif 3805 supportNew[0] = (c - cStart)*8 + 1+4; 3806 supportNew[1] = (c - cStart)*8 + 2+4; 3807 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3808 #if defined(PETSC_USE_DEBUG) 3809 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3810 for (p = 0; p < 2; ++p) { 3811 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 3812 } 3813 #endif 3814 ++newp; 3815 } 3816 /* Split Edges have 2 vertices and the same faces as the parent */ 3817 for (e = eStart; e < eEnd; ++e) { 3818 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3819 3820 for (r = 0; r < 2; ++r) { 3821 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3822 const PetscInt *cone, *ornt, *support; 3823 PetscInt coneNew[2], coneSize, c, supportSize, s; 3824 3825 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3826 coneNew[0] = vStartNew + (cone[0] - vStart); 3827 coneNew[1] = vStartNew + (cone[1] - vStart); 3828 coneNew[(r+1)%2] = newv; 3829 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3830 #if defined(PETSC_USE_DEBUG) 3831 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 3832 for (p = 0; p < 2; ++p) { 3833 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 3834 } 3835 #endif 3836 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3837 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3838 for (s = 0; s < supportSize; ++s) { 3839 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3840 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3841 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3842 for (c = 0; c < coneSize; ++c) { 3843 if (cone[c] == e) break; 3844 } 3845 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 3846 } 3847 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3848 #if defined(PETSC_USE_DEBUG) 3849 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 3850 for (p = 0; p < supportSize; ++p) { 3851 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 3852 } 3853 #endif 3854 } 3855 } 3856 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 3857 for (f = fStart; f < fEnd; ++f) { 3858 const PetscInt *cone, *ornt, *support; 3859 PetscInt coneSize, supportSize, s; 3860 3861 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3862 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3863 for (r = 0; r < 3; ++r) { 3864 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 3865 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 3866 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 3867 -1, -1, 1, 6, 0, 4, 3868 2, 5, 3, 4, -1, -1, 3869 -1, -1, 3, 6, 2, 7}; 3870 3871 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3872 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 3873 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 3874 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3875 #if defined(PETSC_USE_DEBUG) 3876 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 3877 for (p = 0; p < 2; ++p) { 3878 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 3879 } 3880 #endif 3881 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 3882 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 3883 for (s = 0; s < supportSize; ++s) { 3884 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3885 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3886 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3887 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 3888 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 3889 er = GetTriMidEdgeInverse_Static(ornt[c], r); 3890 if (er == eint[c]) { 3891 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 3892 } else { 3893 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 3894 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 3895 } 3896 } 3897 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3898 #if defined(PETSC_USE_DEBUG) 3899 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 3900 for (p = 0; p < intFaces; ++p) { 3901 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 3902 } 3903 #endif 3904 } 3905 } 3906 /* Interior edges have 2 vertices and 4 faces */ 3907 for (c = cStart; c < cEnd; ++c) { 3908 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3909 const PetscInt *cone, *ornt, *fcone; 3910 PetscInt coneNew[2], supportNew[4], find; 3911 3912 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3913 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3914 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 3915 find = GetTriEdge_Static(ornt[0], 0); 3916 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3917 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 3918 find = GetTriEdge_Static(ornt[2], 1); 3919 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3920 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3921 #if defined(PETSC_USE_DEBUG) 3922 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 3923 for (p = 0; p < 2; ++p) { 3924 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 3925 } 3926 #endif 3927 supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 3928 supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 3929 supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 3930 supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 3931 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3932 #if defined(PETSC_USE_DEBUG) 3933 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 3934 for (p = 0; p < 4; ++p) { 3935 if ((supportNew[p] < fStartNew) || (supportNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportNew[p], fStartNew, fEndNew); 3936 } 3937 #endif 3938 } 3939 /* Old vertices have identical supports */ 3940 for (v = vStart; v < vEnd; ++v) { 3941 const PetscInt newp = vStartNew + (v - vStart); 3942 const PetscInt *support, *cone; 3943 PetscInt size, s; 3944 3945 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3946 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3947 for (s = 0; s < size; ++s) { 3948 PetscInt r = 0; 3949 3950 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3951 if (cone[1] == v) r = 1; 3952 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3953 } 3954 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3955 #if defined(PETSC_USE_DEBUG) 3956 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3957 for (p = 0; p < size; ++p) { 3958 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", supportRef[p], eStartNew, eEndNew); 3959 } 3960 #endif 3961 } 3962 /* Edge vertices have 2 + face*2 + 0/1 supports */ 3963 for (e = eStart; e < eEnd; ++e) { 3964 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3965 const PetscInt *cone, *support; 3966 PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 3967 3968 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3969 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3970 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3971 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3972 for (s = 0; s < size; ++s) { 3973 PetscInt r = 0; 3974 3975 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3976 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3977 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 3978 supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 3979 supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 3980 } 3981 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3982 for (s = 0; s < starSize*2; s += 2) { 3983 const PetscInt *cone, *ornt; 3984 PetscInt e01, e23; 3985 3986 if ((star[s] >= cStart) && (star[s] < cEnd)) { 3987 /* Check edge 0-1 */ 3988 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3989 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3990 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 3991 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 3992 /* Check edge 2-3 */ 3993 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3994 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3995 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 3996 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 3997 if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 3998 } 3999 } 4000 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4001 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4002 #if defined(PETSC_USE_DEBUG) 4003 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 4004 for (p = 0; p < 2+size*2+cellSize; ++p) { 4005 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", supportRef[p], eStartNew, eEndNew); 4006 } 4007 #endif 4008 } 4009 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4010 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 4011 break; 4012 case REFINER_HYBRID_SIMPLEX_3D: 4013 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 4014 /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 4015 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 4016 for (c = cStart; c < cMax; ++c) { 4017 const PetscInt newp = cStartNew + (c - cStart)*8; 4018 const PetscInt *cone, *ornt; 4019 PetscInt coneNew[4], orntNew[4]; 4020 4021 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4022 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4023 /* A tetrahedron: {0, a, c, d} */ 4024 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 4025 orntNew[0] = ornt[0]; 4026 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 4027 orntNew[1] = ornt[1]; 4028 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 4029 orntNew[2] = ornt[2]; 4030 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 4031 orntNew[3] = 0; 4032 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4033 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4034 #if defined(PETSC_USE_DEBUG) 4035 if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+0, cStartNew, cMaxNew); 4036 for (p = 0; p < 4; ++p) { 4037 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 4038 } 4039 #endif 4040 /* B tetrahedron: {a, 1, b, e} */ 4041 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 4042 orntNew[0] = ornt[0]; 4043 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 4044 orntNew[1] = ornt[1]; 4045 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 4046 orntNew[2] = 0; 4047 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 4048 orntNew[3] = ornt[3]; 4049 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4050 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4051 #if defined(PETSC_USE_DEBUG) 4052 if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+1, cStartNew, cMaxNew); 4053 for (p = 0; p < 4; ++p) { 4054 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 4055 } 4056 #endif 4057 /* C tetrahedron: {c, b, 2, f} */ 4058 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 4059 orntNew[0] = ornt[0]; 4060 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 4061 orntNew[1] = 0; 4062 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 4063 orntNew[2] = ornt[2]; 4064 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 4065 orntNew[3] = ornt[3]; 4066 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4067 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4068 #if defined(PETSC_USE_DEBUG) 4069 if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+2, cStartNew, cMaxNew); 4070 for (p = 0; p < 4; ++p) { 4071 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 4072 } 4073 #endif 4074 /* D tetrahedron: {d, e, f, 3} */ 4075 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 4076 orntNew[0] = 0; 4077 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 4078 orntNew[1] = ornt[1]; 4079 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 4080 orntNew[2] = ornt[2]; 4081 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 4082 orntNew[3] = ornt[3]; 4083 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4084 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4085 #if defined(PETSC_USE_DEBUG) 4086 if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+3, cStartNew, cMaxNew); 4087 for (p = 0; p < 4; ++p) { 4088 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 4089 } 4090 #endif 4091 /* A' tetrahedron: {d, a, c, f} */ 4092 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 4093 orntNew[0] = -3; 4094 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 4095 orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0); 4096 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4097 orntNew[2] = 0; 4098 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4099 orntNew[3] = 2; 4100 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 4101 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 4102 #if defined(PETSC_USE_DEBUG) 4103 if ((newp+4 < cStartNew) || (newp+4 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+4, cStartNew, cMaxNew); 4104 for (p = 0; p < 4; ++p) { 4105 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 4106 } 4107 #endif 4108 /* B' tetrahedron: {e, b, a, f} */ 4109 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 4110 orntNew[0] = -3; 4111 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4112 orntNew[1] = 1; 4113 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4114 orntNew[2] = 0; 4115 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 4116 orntNew[3] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 0)+1) : GetTriMidEdge_Static(ornt[3], 0); 4117 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 4118 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 4119 #if defined(PETSC_USE_DEBUG) 4120 if ((newp+5 < cStartNew) || (newp+5 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+5, cStartNew, cMaxNew); 4121 for (p = 0; p < 4; ++p) { 4122 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 4123 } 4124 #endif 4125 /* C' tetrahedron: {b, f, c, a} */ 4126 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 4127 orntNew[0] = -3; 4128 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 4129 orntNew[1] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2); 4130 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4131 orntNew[2] = -3; 4132 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4133 orntNew[3] = -2; 4134 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 4135 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 4136 #if defined(PETSC_USE_DEBUG) 4137 if ((newp+6 < cStartNew) || (newp+6 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+6, cStartNew, cMaxNew); 4138 for (p = 0; p < 4; ++p) { 4139 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 4140 } 4141 #endif 4142 /* D' tetrahedron: {f, e, d, a} */ 4143 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 4144 orntNew[0] = -3; 4145 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4146 orntNew[1] = -3; 4147 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 4148 orntNew[2] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 0)+1) : GetTriMidEdge_Static(ornt[1], 0); 4149 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4150 orntNew[3] = -3; 4151 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 4152 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 4153 #if defined(PETSC_USE_DEBUG) 4154 if ((newp+7 < cStartNew) || (newp+7 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+7, cStartNew, cMaxNew); 4155 for (p = 0; p < 4; ++p) { 4156 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 4157 } 4158 #endif 4159 } 4160 /* Hybrid cells have 5 faces */ 4161 for (c = cMax; c < cEnd; ++c) { 4162 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4; 4163 const PetscInt *cone, *ornt, *fornt; 4164 PetscInt coneNew[5], orntNew[5], o, of, i; 4165 4166 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4167 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4168 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 4169 o = ornt[0] < 0 ? -1 : 1; 4170 for (r = 0; r < 3; ++r) { 4171 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 4172 orntNew[0] = ornt[0]; 4173 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 4174 orntNew[1] = ornt[1]; 4175 of = fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? -1 : 1; 4176 i = GetTriEdgeInverse_Static(ornt[0], r) + 2; 4177 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (o*of < 0 ? 1 : 0); 4178 orntNew[i] = 0; 4179 i = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2; 4180 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 4181 orntNew[i] = 0; 4182 of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1; 4183 i = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2; 4184 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], (r+2)%3)] - fMax)*2 + (o*of < 0 ? 0 : 1); 4185 orntNew[i] = 0; 4186 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4187 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4188 #if defined(PETSC_USE_DEBUG) 4189 if ((newp+r < cMaxNew) || (newp+r >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid cell [%D, %D)", newp+r, cMaxNew, cEndNew); 4190 for (p = 0; p < 2; ++p) { 4191 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 4192 } 4193 for (p = 2; p < 5; ++p) { 4194 if ((coneNew[p] < fMaxNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", coneNew[p], fMaxNew, fEndNew); 4195 } 4196 #endif 4197 } 4198 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 4199 orntNew[0] = 0; 4200 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 4201 orntNew[1] = 0; 4202 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 4203 orntNew[2] = 0; 4204 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 4205 orntNew[3] = 0; 4206 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 4207 orntNew[4] = 0; 4208 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4209 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4210 #if defined(PETSC_USE_DEBUG) 4211 if ((newp+3 < cMaxNew) || (newp+3 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid cell [%D, %D)", newp+3, cMaxNew, cEndNew); 4212 for (p = 0; p < 2; ++p) { 4213 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 4214 } 4215 for (p = 2; p < 5; ++p) { 4216 if ((coneNew[p] < fMaxNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", coneNew[p], fMaxNew, fEndNew); 4217 } 4218 #endif 4219 } 4220 /* Split faces have 3 edges and the same cells as the parent */ 4221 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4222 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 4223 for (f = fStart; f < fMax; ++f) { 4224 const PetscInt newp = fStartNew + (f - fStart)*4; 4225 const PetscInt *cone, *ornt, *support; 4226 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 4227 4228 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4229 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4230 /* A triangle */ 4231 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 4232 orntNew[0] = ornt[0]; 4233 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 4234 orntNew[1] = -2; 4235 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 4236 orntNew[2] = ornt[2]; 4237 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4238 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4239 #if defined(PETSC_USE_DEBUG) 4240 if ((newp+0 < fStartNew) || (newp+0 >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp+0, fStartNew, fMaxNew); 4241 for (p = 0; p < 3; ++p) { 4242 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 4243 } 4244 #endif 4245 /* B triangle */ 4246 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 4247 orntNew[0] = ornt[0]; 4248 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 4249 orntNew[1] = ornt[1]; 4250 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 4251 orntNew[2] = -2; 4252 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4253 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4254 #if defined(PETSC_USE_DEBUG) 4255 if ((newp+1 < fStartNew) || (newp+1 >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp+1, fStartNew, fMaxNew); 4256 for (p = 0; p < 3; ++p) { 4257 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 4258 } 4259 #endif 4260 /* C triangle */ 4261 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 4262 orntNew[0] = -2; 4263 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 4264 orntNew[1] = ornt[1]; 4265 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 4266 orntNew[2] = ornt[2]; 4267 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4268 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4269 #if defined(PETSC_USE_DEBUG) 4270 if ((newp+2 < fStartNew) || (newp+2 >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp+2, fStartNew, fMaxNew); 4271 for (p = 0; p < 3; ++p) { 4272 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 4273 } 4274 #endif 4275 /* D triangle */ 4276 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 4277 orntNew[0] = 0; 4278 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 4279 orntNew[1] = 0; 4280 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 4281 orntNew[2] = 0; 4282 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4283 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4284 #if defined(PETSC_USE_DEBUG) 4285 if ((newp+3 < fStartNew) || (newp+3 >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp+3, fStartNew, fMaxNew); 4286 for (p = 0; p < 3; ++p) { 4287 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 4288 } 4289 #endif 4290 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4291 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4292 for (r = 0; r < 4; ++r) { 4293 for (s = 0; s < supportSize; ++s) { 4294 PetscInt subf; 4295 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4296 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4297 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4298 for (c = 0; c < coneSize; ++c) { 4299 if (cone[c] == f) break; 4300 } 4301 subf = GetTriSubfaceInverse_Static(ornt[c], r); 4302 if (support[s] < cMax) { 4303 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 4304 } else { 4305 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf); 4306 } 4307 } 4308 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 4309 #if defined(PETSC_USE_DEBUG) 4310 if ((newp+r < fStartNew) || (newp+r >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp+r, fStartNew, fMaxNew); 4311 for (p = 0; p < supportSize; ++p) { 4312 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an interior or hybrid cell [%D, %D)", supportRef[p], cStartNew, cEndNew); 4313 } 4314 #endif 4315 } 4316 } 4317 /* Interior cell faces have 3 edges and 2 cells */ 4318 for (c = cStart; c < cMax; ++c) { 4319 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 4320 const PetscInt *cone, *ornt; 4321 PetscInt coneNew[3], orntNew[3]; 4322 PetscInt supportNew[2]; 4323 4324 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4325 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4326 /* Face A: {c, a, d} */ 4327 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 4328 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4329 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 4330 orntNew[1] = ornt[1] < 0 ? -2 : 0; 4331 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2); 4332 orntNew[2] = ornt[2] < 0 ? -2 : 0; 4333 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4334 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4335 #if defined(PETSC_USE_DEBUG) 4336 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4337 for (p = 0; p < 3; ++p) { 4338 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 4339 } 4340 #endif 4341 supportNew[0] = (c - cStart)*8 + 0; 4342 supportNew[1] = (c - cStart)*8 + 0+4; 4343 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4344 #if defined(PETSC_USE_DEBUG) 4345 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4346 for (p = 0; p < 2; ++p) { 4347 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cMaxNew); 4348 } 4349 #endif 4350 ++newp; 4351 /* Face B: {a, b, e} */ 4352 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 4353 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4354 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0); 4355 orntNew[1] = ornt[3] < 0 ? -2 : 0; 4356 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 4357 orntNew[2] = ornt[1] < 0 ? -2 : 0; 4358 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4359 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4360 #if defined(PETSC_USE_DEBUG) 4361 if ((newp+1 < fStartNew) || (newp+1 >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp+1, fStartNew, fMaxNew); 4362 for (p = 0; p < 3; ++p) { 4363 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 4364 } 4365 #endif 4366 supportNew[0] = (c - cStart)*8 + 1; 4367 supportNew[1] = (c - cStart)*8 + 1+4; 4368 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4369 #if defined(PETSC_USE_DEBUG) 4370 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4371 for (p = 0; p < 2; ++p) { 4372 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cMaxNew); 4373 } 4374 #endif 4375 ++newp; 4376 /* Face C: {c, f, b} */ 4377 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 4378 orntNew[0] = ornt[2] < 0 ? -2 : 0; 4379 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 4380 orntNew[1] = ornt[3] < 0 ? -2 : 0; 4381 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1); 4382 orntNew[2] = ornt[0] < 0 ? -2 : 0; 4383 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4384 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4385 #if defined(PETSC_USE_DEBUG) 4386 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4387 for (p = 0; p < 3; ++p) { 4388 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 4389 } 4390 #endif 4391 supportNew[0] = (c - cStart)*8 + 2; 4392 supportNew[1] = (c - cStart)*8 + 2+4; 4393 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4394 #if defined(PETSC_USE_DEBUG) 4395 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4396 for (p = 0; p < 2; ++p) { 4397 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cMaxNew); 4398 } 4399 #endif 4400 ++newp; 4401 /* Face D: {d, e, f} */ 4402 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0); 4403 orntNew[0] = ornt[1] < 0 ? -2 : 0; 4404 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 4405 orntNew[1] = ornt[3] < 0 ? -2 : 0; 4406 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 4407 orntNew[2] = ornt[2] < 0 ? -2 : 0; 4408 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4409 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4410 #if defined(PETSC_USE_DEBUG) 4411 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4412 for (p = 0; p < 3; ++p) { 4413 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 4414 } 4415 #endif 4416 supportNew[0] = (c - cStart)*8 + 3; 4417 supportNew[1] = (c - cStart)*8 + 3+4; 4418 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4419 #if defined(PETSC_USE_DEBUG) 4420 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4421 for (p = 0; p < 2; ++p) { 4422 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cMaxNew); 4423 } 4424 #endif 4425 ++newp; 4426 /* Face E: {d, f, a} */ 4427 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 4428 orntNew[0] = ornt[2] < 0 ? 0 : -2; 4429 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4430 orntNew[1] = -2; 4431 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 4432 orntNew[2] = ornt[1] < 0 ? -2 : 0; 4433 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4434 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4435 #if defined(PETSC_USE_DEBUG) 4436 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4437 for (p = 0; p < 3; ++p) { 4438 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 4439 } 4440 #endif 4441 supportNew[0] = (c - cStart)*8 + 0+4; 4442 supportNew[1] = (c - cStart)*8 + 3+4; 4443 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4444 #if defined(PETSC_USE_DEBUG) 4445 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4446 for (p = 0; p < 2; ++p) { 4447 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cMaxNew); 4448 } 4449 #endif 4450 ++newp; 4451 /* Face F: {c, a, f} */ 4452 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 4453 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4454 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4455 orntNew[1] = 0; 4456 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 4457 orntNew[2] = ornt[2] < 0 ? 0 : -2; 4458 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4459 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4460 #if defined(PETSC_USE_DEBUG) 4461 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4462 for (p = 0; p < 3; ++p) { 4463 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 4464 } 4465 #endif 4466 supportNew[0] = (c - cStart)*8 + 0+4; 4467 supportNew[1] = (c - cStart)*8 + 2+4; 4468 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4469 #if defined(PETSC_USE_DEBUG) 4470 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4471 for (p = 0; p < 2; ++p) { 4472 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cMaxNew); 4473 } 4474 #endif 4475 ++newp; 4476 /* Face G: {e, a, f} */ 4477 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 4478 orntNew[0] = ornt[1] < 0 ? -2 : 0; 4479 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4480 orntNew[1] = 0; 4481 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 4482 orntNew[2] = ornt[3] < 0 ? 0 : -2; 4483 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4484 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4485 #if defined(PETSC_USE_DEBUG) 4486 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4487 for (p = 0; p < 3; ++p) { 4488 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 4489 } 4490 #endif 4491 supportNew[0] = (c - cStart)*8 + 1+4; 4492 supportNew[1] = (c - cStart)*8 + 3+4; 4493 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4494 #if defined(PETSC_USE_DEBUG) 4495 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4496 for (p = 0; p < 2; ++p) { 4497 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cMaxNew); 4498 } 4499 #endif 4500 ++newp; 4501 /* Face H: {a, b, f} */ 4502 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 4503 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4504 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 4505 orntNew[1] = ornt[3] < 0 ? 0 : -2; 4506 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4507 orntNew[2] = -2; 4508 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4509 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4510 #if defined(PETSC_USE_DEBUG) 4511 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4512 for (p = 0; p < 3; ++p) { 4513 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 4514 } 4515 #endif 4516 supportNew[0] = (c - cStart)*8 + 1+4; 4517 supportNew[1] = (c - cStart)*8 + 2+4; 4518 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4519 #if defined(PETSC_USE_DEBUG) 4520 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4521 for (p = 0; p < 2; ++p) { 4522 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cMaxNew); 4523 } 4524 #endif 4525 ++newp; 4526 } 4527 /* Hybrid split faces have 4 edges and same cells */ 4528 for (f = fMax; f < fEnd; ++f) { 4529 const PetscInt *cone, *ornt, *support; 4530 PetscInt coneNew[4], orntNew[4]; 4531 PetscInt supportNew[2], size, s, c; 4532 4533 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4534 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4535 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4536 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4537 for (r = 0; r < 2; ++r) { 4538 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 4539 4540 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 4541 orntNew[0] = ornt[0]; 4542 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 4543 orntNew[1] = ornt[1]; 4544 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 4545 orntNew[2+r] = 0; 4546 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 4547 orntNew[3-r] = 0; 4548 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4549 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4550 #if defined(PETSC_USE_DEBUG) 4551 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 4552 for (p = 0; p < 2; ++p) { 4553 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 4554 } 4555 for (p = 2; p < 4; ++p) { 4556 if ((coneNew[p] < eMaxNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", coneNew[p], eMaxNew, eEndNew); 4557 } 4558 #endif 4559 for (s = 0; s < size; ++s) { 4560 const PetscInt *coneCell, *orntCell, *fornt; 4561 PetscInt o, of; 4562 4563 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4564 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4565 o = orntCell[0] < 0 ? -1 : 1; 4566 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 4567 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]); 4568 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 4569 of = fornt[c-2] < 0 ? -1 : 1; 4570 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 4571 } 4572 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4573 #if defined(PETSC_USE_DEBUG) 4574 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 4575 for (p = 0; p < size; ++p) { 4576 if ((supportNew[p] < cMaxNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid cell [%D, %D)", supportNew[p], cMaxNew, cEndNew); 4577 } 4578 #endif 4579 } 4580 } 4581 /* Hybrid cell faces have 4 edges and 2 cells */ 4582 for (c = cMax; c < cEnd; ++c) { 4583 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 4584 const PetscInt *cone, *ornt; 4585 PetscInt coneNew[4], orntNew[4]; 4586 PetscInt supportNew[2]; 4587 4588 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4589 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4590 for (r = 0; r < 3; ++r) { 4591 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3; 4592 orntNew[0] = 0; 4593 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3; 4594 orntNew[1] = 0; 4595 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax); 4596 orntNew[2] = 0; 4597 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r] - fMax); 4598 orntNew[3] = 0; 4599 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4600 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4601 #if defined(PETSC_USE_DEBUG) 4602 if ((newp+r < fMaxNew) || (newp+r >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp+r, fMaxNew, fEndNew); 4603 for (p = 0; p < 2; ++p) { 4604 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 4605 } 4606 for (p = 2; p < 4; ++p) { 4607 if ((coneNew[p] < eMaxNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", coneNew[p], eMaxNew, eEndNew); 4608 } 4609 #endif 4610 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 4611 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 4612 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 4613 #if defined(PETSC_USE_DEBUG) 4614 if ((newp+r < fMaxNew) || (newp+r >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp+r, fMaxNew, fEndNew); 4615 for (p = 0; p < 2; ++p) { 4616 if ((supportNew[p] < cMaxNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid cell [%D, %D)", supportNew[p], cMaxNew, cEndNew); 4617 } 4618 #endif 4619 } 4620 } 4621 /* Interior split edges have 2 vertices and the same faces as the parent */ 4622 for (e = eStart; e < eMax; ++e) { 4623 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4624 4625 for (r = 0; r < 2; ++r) { 4626 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4627 const PetscInt *cone, *ornt, *support; 4628 PetscInt coneNew[2], coneSize, c, supportSize, s; 4629 4630 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4631 coneNew[0] = vStartNew + (cone[0] - vStart); 4632 coneNew[1] = vStartNew + (cone[1] - vStart); 4633 coneNew[(r+1)%2] = newv; 4634 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4635 #if defined(PETSC_USE_DEBUG) 4636 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4637 for (p = 0; p < 2; ++p) { 4638 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 4639 } 4640 #endif 4641 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4642 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4643 for (s = 0; s < supportSize; ++s) { 4644 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4645 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4646 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4647 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 4648 if (support[s] < fMax) { 4649 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 4650 } else { 4651 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 4652 } 4653 } 4654 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4655 #if defined(PETSC_USE_DEBUG) 4656 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4657 for (p = 0; p < supportSize; ++p) { 4658 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an interior or hybrid face [%D, %D)", supportRef[p], fStartNew, fEndNew); 4659 } 4660 #endif 4661 } 4662 } 4663 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 4664 for (f = fStart; f < fMax; ++f) { 4665 const PetscInt *cone, *ornt, *support; 4666 PetscInt coneSize, supportSize, s; 4667 4668 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4669 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4670 for (r = 0; r < 3; ++r) { 4671 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 4672 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 4673 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 4674 -1, -1, 1, 6, 0, 4, 4675 2, 5, 3, 4, -1, -1, 4676 -1, -1, 3, 6, 2, 7}; 4677 4678 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4679 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 4680 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 4681 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4682 #if defined(PETSC_USE_DEBUG) 4683 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4684 for (p = 0; p < 2; ++p) { 4685 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 4686 } 4687 #endif 4688 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 4689 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 4690 for (s = 0; s < supportSize; ++s) { 4691 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4692 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4693 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4694 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 4695 if (support[s] < cMax) { 4696 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 4697 er = GetTriMidEdgeInverse_Static(ornt[c], r); 4698 if (er == eint[c]) { 4699 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 4700 } else { 4701 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 4702 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 4703 } 4704 } else { 4705 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3; 4706 } 4707 } 4708 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4709 #if defined(PETSC_USE_DEBUG) 4710 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4711 for (p = 0; p < intFaces; ++p) { 4712 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an interior or hybrid face [%D, %D)", supportRef[p], fStartNew, fEndNew); 4713 } 4714 #endif 4715 } 4716 } 4717 /* Interior cell edges have 2 vertices and 4 faces */ 4718 for (c = cStart; c < cMax; ++c) { 4719 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4720 const PetscInt *cone, *ornt, *fcone; 4721 PetscInt coneNew[2], supportNew[4], find; 4722 4723 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4724 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4725 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 4726 find = GetTriEdge_Static(ornt[0], 0); 4727 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4728 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 4729 find = GetTriEdge_Static(ornt[2], 1); 4730 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4731 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4732 #if defined(PETSC_USE_DEBUG) 4733 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4734 for (p = 0; p < 2; ++p) { 4735 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 4736 } 4737 #endif 4738 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4739 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4740 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4741 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4742 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4743 #if defined(PETSC_USE_DEBUG) 4744 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4745 for (p = 0; p < 4; ++p) { 4746 if ((supportNew[p] < fStartNew) || (supportNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportNew[p], fStartNew, fMaxNew); 4747 } 4748 #endif 4749 } 4750 /* Hybrid edges have two vertices and the same faces */ 4751 for (e = eMax; e < eEnd; ++e) { 4752 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 4753 const PetscInt *cone, *support, *fcone; 4754 PetscInt coneNew[2], size, fsize, s; 4755 4756 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4757 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4758 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4759 coneNew[0] = vStartNew + (cone[0] - vStart); 4760 coneNew[1] = vStartNew + (cone[1] - vStart); 4761 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4762 #if defined(PETSC_USE_DEBUG) 4763 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4764 for (p = 0; p < 2; ++p) { 4765 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 4766 } 4767 #endif 4768 for (s = 0; s < size; ++s) { 4769 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 4770 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 4771 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 4772 if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]); 4773 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 4774 } 4775 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4776 #if defined(PETSC_USE_DEBUG) 4777 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4778 for (p = 0; p < size; ++p) { 4779 if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", supportRef[p], fMaxNew, fEndNew); 4780 } 4781 #endif 4782 } 4783 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 4784 for (f = fMax; f < fEnd; ++f) { 4785 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 4786 const PetscInt *cone, *support, *ccone, *cornt; 4787 PetscInt coneNew[2], size, csize, s; 4788 4789 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4790 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4791 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4792 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 4793 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 4794 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4795 #if defined(PETSC_USE_DEBUG) 4796 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4797 for (p = 0; p < 2; ++p) { 4798 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 4799 } 4800 #endif 4801 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 4802 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 4803 for (s = 0; s < size; ++s) { 4804 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 4805 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 4806 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 4807 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 4808 if ((c < 2) || (c >= csize)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Hybrid face %D is not in cone of hybrid cell %D", f, support[s]); 4809 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2; 4810 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3; 4811 } 4812 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4813 #if defined(PETSC_USE_DEBUG) 4814 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4815 for (p = 0; p < 2+size*2; ++p) { 4816 if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", supportRef[p], fMaxNew, fEndNew); 4817 } 4818 #endif 4819 } 4820 /* Interior vertices have identical supports */ 4821 for (v = vStart; v < vEnd; ++v) { 4822 const PetscInt newp = vStartNew + (v - vStart); 4823 const PetscInt *support, *cone; 4824 PetscInt size, s; 4825 4826 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4827 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4828 for (s = 0; s < size; ++s) { 4829 PetscInt r = 0; 4830 4831 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4832 if (cone[1] == v) r = 1; 4833 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4834 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 4835 } 4836 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4837 #if defined(PETSC_USE_DEBUG) 4838 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 4839 for (p = 0; p < size; ++p) { 4840 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an interior or hybrid edge [%D, %D)", supportRef[p], eStartNew, eEndNew); 4841 } 4842 #endif 4843 } 4844 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 4845 for (e = eStart; e < eMax; ++e) { 4846 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4847 const PetscInt *cone, *support; 4848 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 4849 4850 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4851 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4852 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4853 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4854 for (s = 0; s < size; ++s) { 4855 PetscInt r = 0; 4856 4857 if (support[s] < fMax) { 4858 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4859 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4860 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 4861 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 4862 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 4863 faceSize += 2; 4864 } else { 4865 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 4866 ++faceSize; 4867 } 4868 } 4869 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4870 for (s = 0; s < starSize*2; s += 2) { 4871 const PetscInt *cone, *ornt; 4872 PetscInt e01, e23; 4873 4874 if ((star[s] >= cStart) && (star[s] < cMax)) { 4875 /* Check edge 0-1 */ 4876 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 4877 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 4878 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 4879 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 4880 /* Check edge 2-3 */ 4881 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 4882 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 4883 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 4884 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 4885 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 4886 } 4887 } 4888 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4889 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4890 #if defined(PETSC_USE_DEBUG) 4891 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 4892 for (p = 0; p < 2+faceSize+cellSize; ++p) { 4893 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an interior or hybrid edge [%D, %D)", supportRef[p], eStartNew, eEndNew); 4894 } 4895 #endif 4896 } 4897 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4898 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 4899 break; 4900 case REFINER_SIMPLEX_TO_HEX_3D: 4901 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 4902 /* All cells have 6 faces */ 4903 for (c = cStart; c < cEnd; ++c) { 4904 const PetscInt newp = cStartNew + (c - cStart)*4; 4905 const PetscInt *cone, *ornt; 4906 PetscInt coneNew[6]; 4907 PetscInt orntNew[6]; 4908 4909 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4910 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4911 /* A hex */ 4912 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 4913 orntNew[0] = ornt[0] < 0 ? -1 : 1; 4914 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* T */ 4915 orntNew[1] = -4; 4916 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */ 4917 orntNew[2] = ornt[2] < 0 ? -1 : 1; 4918 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* K */ 4919 orntNew[3] = -1; 4920 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* R */ 4921 orntNew[4] = 0; 4922 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */ 4923 orntNew[5] = ornt[1] < 0 ? -1 : 1; 4924 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4925 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4926 #if defined(PETSC_USE_DEBUG) 4927 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+0, cStartNew, cEndNew); 4928 for (p = 0; p < 6; ++p) { 4929 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 4930 } 4931 #endif 4932 /* B hex */ 4933 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 4934 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4935 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* T */ 4936 orntNew[1] = 0; 4937 coneNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* F */ 4938 orntNew[2] = 0; 4939 coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */ 4940 orntNew[3] = ornt[3] < 0 ? -2 : 0; 4941 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* R */ 4942 orntNew[4] = 0; 4943 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */ 4944 orntNew[5] = ornt[1] < 0 ? -4 : 2; 4945 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4946 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4947 #if defined(PETSC_USE_DEBUG) 4948 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+1, cStartNew, cEndNew); 4949 for (p = 0; p < 6; ++p) { 4950 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 4951 } 4952 #endif 4953 /* C hex */ 4954 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 4955 orntNew[0] = ornt[0] < 0 ? -4 : 2; 4956 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* T */ 4957 orntNew[1] = -4; 4958 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */ 4959 orntNew[2] = ornt[2] < 0 ? -2 : 0; 4960 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* K */ 4961 orntNew[3] = -1; 4962 coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */ 4963 orntNew[4] = ornt[3] < 0 ? -1 : 1; 4964 coneNew[5] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* L */ 4965 orntNew[5] = -4; 4966 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4967 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4968 #if defined(PETSC_USE_DEBUG) 4969 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+2, cStartNew, cEndNew); 4970 for (p = 0; p < 6; ++p) { 4971 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 4972 } 4973 #endif 4974 /* D hex */ 4975 coneNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* B */ 4976 orntNew[0] = 0; 4977 coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */ 4978 orntNew[1] = ornt[3] < 0 ? -1 : 1; 4979 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */ 4980 orntNew[2] = ornt[2] < 0 ? -4 : 2; 4981 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* K */ 4982 orntNew[3] = -1; 4983 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* R */ 4984 orntNew[4] = 0; 4985 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */ 4986 orntNew[5] = ornt[1] < 0 ? -2 : 0; 4987 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4988 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4989 #if defined(PETSC_USE_DEBUG) 4990 if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+3, cStartNew, cEndNew); 4991 for (p = 0; p < 6; ++p) { 4992 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 4993 } 4994 #endif 4995 } 4996 /* Split faces have 4 edges and the same cells as the parent */ 4997 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4998 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 4999 for (f = fStart; f < fEnd; ++f) { 5000 const PetscInt newp = fStartNew + (f - fStart)*3; 5001 const PetscInt *cone, *ornt, *support; 5002 PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s; 5003 5004 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5005 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5006 /* A quad */ 5007 coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 5008 orntNew[0] = ornt[2]; 5009 coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 5010 orntNew[1] = ornt[0]; 5011 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 5012 orntNew[2] = 0; 5013 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 5014 orntNew[3] = -2; 5015 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5016 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5017 #if defined(PETSC_USE_DEBUG) 5018 if ((newp+0 < fStartNew) || (newp+0 >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp+0, fStartNew, fEndNew); 5019 for (p = 0; p < 4; ++p) { 5020 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 5021 } 5022 #endif 5023 /* B quad */ 5024 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 5025 orntNew[0] = ornt[0]; 5026 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 5027 orntNew[1] = ornt[1]; 5028 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 5029 orntNew[2] = 0; 5030 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 5031 orntNew[3] = -2; 5032 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5033 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5034 #if defined(PETSC_USE_DEBUG) 5035 if ((newp+1 < fStartNew) || (newp+1 >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp+1, fStartNew, fEndNew); 5036 for (p = 0; p < 4; ++p) { 5037 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 5038 } 5039 #endif 5040 /* C quad */ 5041 coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 5042 orntNew[0] = ornt[1]; 5043 coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 5044 orntNew[1] = ornt[2]; 5045 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 5046 orntNew[2] = 0; 5047 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 5048 orntNew[3] = -2; 5049 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5050 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5051 #if defined(PETSC_USE_DEBUG) 5052 if ((newp+2 < fStartNew) || (newp+2 >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp+2, fStartNew, fEndNew); 5053 for (p = 0; p < 4; ++p) { 5054 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 5055 } 5056 #endif 5057 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5058 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5059 for (r = 0; r < 3; ++r) { 5060 for (s = 0; s < supportSize; ++s) { 5061 PetscInt subf; 5062 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5063 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5064 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5065 for (c = 0; c < coneSize; ++c) { 5066 if (cone[c] == f) break; 5067 } 5068 subf = GetTriSubfaceInverse_Static(ornt[c], r); 5069 supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf]; 5070 } 5071 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 5072 #if defined(PETSC_USE_DEBUG) 5073 if ((newp+r < fStartNew) || (newp+r >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp+r, fStartNew, fEndNew); 5074 for (p = 0; p < supportSize; ++p) { 5075 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportRef[p], cStartNew, cEndNew); 5076 } 5077 #endif 5078 } 5079 } 5080 /* Interior faces have 4 edges and 2 cells */ 5081 for (c = cStart; c < cEnd; ++c) { 5082 PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6; 5083 const PetscInt *cone, *ornt; 5084 PetscInt coneNew[4], orntNew[4]; 5085 PetscInt supportNew[2]; 5086 5087 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5088 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5089 /* Face {a, g, m, h} */ 5090 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 5091 orntNew[0] = 0; 5092 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5093 orntNew[1] = 0; 5094 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5095 orntNew[2] = -2; 5096 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 5097 orntNew[3] = -2; 5098 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5099 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5100 #if defined(PETSC_USE_DEBUG) 5101 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5102 for (p = 0; p < 4; ++p) { 5103 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 5104 } 5105 #endif 5106 supportNew[0] = (c - cStart)*4 + 0; 5107 supportNew[1] = (c - cStart)*4 + 1; 5108 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5109 #if defined(PETSC_USE_DEBUG) 5110 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5111 for (p = 0; p < 2; ++p) { 5112 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 5113 } 5114 #endif 5115 ++newp; 5116 /* Face {g, b, l , m} */ 5117 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 5118 orntNew[0] = -2; 5119 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0); 5120 orntNew[1] = 0; 5121 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5122 orntNew[2] = 0; 5123 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5124 orntNew[3] = -2; 5125 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5126 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5127 #if defined(PETSC_USE_DEBUG) 5128 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5129 for (p = 0; p < 4; ++p) { 5130 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 5131 } 5132 #endif 5133 supportNew[0] = (c - cStart)*4 + 1; 5134 supportNew[1] = (c - cStart)*4 + 2; 5135 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5136 #if defined(PETSC_USE_DEBUG) 5137 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5138 for (p = 0; p < 2; ++p) { 5139 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 5140 } 5141 #endif 5142 ++newp; 5143 /* Face {c, g, m, i} */ 5144 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 5145 orntNew[0] = 0; 5146 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5147 orntNew[1] = 0; 5148 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5149 orntNew[2] = -2; 5150 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0); 5151 orntNew[3] = -2; 5152 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5153 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5154 #if defined(PETSC_USE_DEBUG) 5155 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5156 for (p = 0; p < 4; ++p) { 5157 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 5158 } 5159 #endif 5160 supportNew[0] = (c - cStart)*4 + 0; 5161 supportNew[1] = (c - cStart)*4 + 2; 5162 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5163 #if defined(PETSC_USE_DEBUG) 5164 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5165 for (p = 0; p < 2; ++p) { 5166 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 5167 } 5168 #endif 5169 ++newp; 5170 /* Face {d, h, m, i} */ 5171 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 5172 orntNew[0] = 0; 5173 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5174 orntNew[1] = 0; 5175 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5176 orntNew[2] = -2; 5177 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2); 5178 orntNew[3] = -2; 5179 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5180 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5181 #if defined(PETSC_USE_DEBUG) 5182 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5183 for (p = 0; p < 4; ++p) { 5184 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 5185 } 5186 #endif 5187 supportNew[0] = (c - cStart)*4 + 0; 5188 supportNew[1] = (c - cStart)*4 + 3; 5189 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5190 #if defined(PETSC_USE_DEBUG) 5191 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5192 for (p = 0; p < 2; ++p) { 5193 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 5194 } 5195 #endif 5196 ++newp; 5197 /* Face {h, m, l, e} */ 5198 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5199 orntNew[0] = 0; 5200 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5201 orntNew[1] = -2; 5202 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1); 5203 orntNew[2] = -2; 5204 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 5205 orntNew[3] = 0; 5206 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5207 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5208 #if defined(PETSC_USE_DEBUG) 5209 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5210 for (p = 0; p < 4; ++p) { 5211 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 5212 } 5213 #endif 5214 supportNew[0] = (c - cStart)*4 + 1; 5215 supportNew[1] = (c - cStart)*4 + 3; 5216 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5217 #if defined(PETSC_USE_DEBUG) 5218 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5219 for (p = 0; p < 2; ++p) { 5220 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 5221 } 5222 #endif 5223 ++newp; 5224 /* Face {i, m, l, f} */ 5225 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5226 orntNew[0] = 0; 5227 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5228 orntNew[1] = -2; 5229 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2); 5230 orntNew[2] = -2; 5231 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1); 5232 orntNew[3] = 0; 5233 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5234 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5235 #if defined(PETSC_USE_DEBUG) 5236 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5237 for (p = 0; p < 4; ++p) { 5238 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 5239 } 5240 #endif 5241 supportNew[0] = (c - cStart)*4 + 2; 5242 supportNew[1] = (c - cStart)*4 + 3; 5243 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5244 #if defined(PETSC_USE_DEBUG) 5245 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5246 for (p = 0; p < 2; ++p) { 5247 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 5248 } 5249 #endif 5250 ++newp; 5251 } 5252 /* Split Edges have 2 vertices and the same faces as the parent */ 5253 for (e = eStart; e < eEnd; ++e) { 5254 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5255 5256 for (r = 0; r < 2; ++r) { 5257 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 5258 const PetscInt *cone, *ornt, *support; 5259 PetscInt coneNew[2], coneSize, c, supportSize, s; 5260 5261 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5262 coneNew[0] = vStartNew + (cone[0] - vStart); 5263 coneNew[1] = vStartNew + (cone[1] - vStart); 5264 coneNew[(r+1)%2] = newv; 5265 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5266 #if defined(PETSC_USE_DEBUG) 5267 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5268 for (p = 0; p < 2; ++p) { 5269 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 5270 } 5271 #endif 5272 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 5273 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5274 for (s = 0; s < supportSize; ++s) { 5275 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5276 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5277 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5278 for (c = 0; c < coneSize; ++c) { 5279 if (cone[c] == e) break; 5280 } 5281 supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3; 5282 } 5283 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5284 #if defined(PETSC_USE_DEBUG) 5285 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5286 for (p = 0; p < supportSize; ++p) { 5287 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 5288 } 5289 #endif 5290 } 5291 } 5292 /* Face edges have 2 vertices and 2 + cell faces supports */ 5293 for (f = fStart; f < fEnd; ++f) { 5294 const PetscInt *cone, *ornt, *support; 5295 PetscInt coneSize, supportSize, s; 5296 5297 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5298 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5299 for (r = 0; r < 3; ++r) { 5300 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 5301 PetscInt coneNew[2]; 5302 PetscInt fint[4][3] = { {0, 1, 2}, 5303 {3, 4, 0}, 5304 {2, 5, 3}, 5305 {1, 4, 5} }; 5306 5307 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5308 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 5309 coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart; 5310 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5311 #if defined(PETSC_USE_DEBUG) 5312 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5313 for (p = 0; p < 2; ++p) { 5314 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 5315 } 5316 #endif 5317 supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3; 5318 supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3; 5319 for (s = 0; s < supportSize; ++s) { 5320 PetscInt er; 5321 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5322 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5323 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5324 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 5325 er = GetTriInteriorEdgeInverse_Static(ornt[c], r); 5326 supportRef[2+s] = fStartNew + (fEnd - fStart)*3 + (support[s] - cStart)*6 + fint[c][er]; 5327 } 5328 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5329 #if defined(PETSC_USE_DEBUG) 5330 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5331 for (p = 0; p < supportSize + 2; ++p) { 5332 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 5333 } 5334 #endif 5335 } 5336 } 5337 /* Interior cell edges have 2 vertices and 3 faces */ 5338 for (c = cStart; c < cEnd; ++c) { 5339 const PetscInt *cone; 5340 PetscInt fint[4][3] = { {0,1,2}, 5341 {0,3,4}, 5342 {2,3,5}, 5343 {1,4,5} } ; 5344 5345 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5346 for (r = 0; r < 4; r++) { 5347 PetscInt coneNew[2], supportNew[3]; 5348 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r; 5349 5350 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 5351 coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd -fStart) + c - cStart; 5352 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5353 #if defined(PETSC_USE_DEBUG) 5354 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5355 for (p = 0; p < 2; ++p) { 5356 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 5357 } 5358 #endif 5359 supportNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][0]; 5360 supportNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][1]; 5361 supportNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][2]; 5362 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5363 #if defined(PETSC_USE_DEBUG) 5364 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5365 for (p = 0; p < 3; ++p) { 5366 if ((supportNew[p] < fStartNew) || (supportNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportNew[p], fStartNew, fEndNew); 5367 } 5368 #endif 5369 } 5370 } 5371 /* Old vertices have identical supports */ 5372 for (v = vStart; v < vEnd; ++v) { 5373 const PetscInt newp = vStartNew + (v - vStart); 5374 const PetscInt *support, *cone; 5375 PetscInt size, s; 5376 5377 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 5378 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 5379 for (s = 0; s < size; ++s) { 5380 PetscInt r = 0; 5381 5382 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5383 if (cone[1] == v) r = 1; 5384 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 5385 } 5386 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5387 #if defined(PETSC_USE_DEBUG) 5388 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5389 for (p = 0; p < size; ++p) { 5390 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", supportRef[p], eStartNew, eEndNew); 5391 } 5392 #endif 5393 } 5394 /* Edge vertices have 2 + faces supports */ 5395 for (e = eStart; e < eEnd; ++e) { 5396 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 5397 const PetscInt *cone, *support; 5398 PetscInt size, s; 5399 5400 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5401 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5402 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 5403 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 5404 for (s = 0; s < size; ++s) { 5405 PetscInt r = 0, coneSize; 5406 5407 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5408 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5409 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 5410 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + r; 5411 } 5412 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5413 #if defined(PETSC_USE_DEBUG) 5414 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5415 for (p = 0; p < 2+size; ++p) { 5416 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", supportRef[p], eStartNew, eEndNew); 5417 } 5418 #endif 5419 } 5420 /* Face vertices have 3 + cells supports */ 5421 for (f = fStart; f < fEnd; ++f) { 5422 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 5423 const PetscInt *cone, *support; 5424 PetscInt size, s; 5425 5426 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5427 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5428 supportRef[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 5429 supportRef[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 5430 supportRef[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 5431 for (s = 0; s < size; ++s) { 5432 PetscInt r = 0, coneSize; 5433 5434 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5435 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5436 for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;} 5437 supportRef[3+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (support[s] - cStart)*4 + r; 5438 } 5439 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5440 #if defined(PETSC_USE_DEBUG) 5441 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5442 for (p = 0; p < 3+size; ++p) { 5443 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", supportRef[p], eStartNew, eEndNew); 5444 } 5445 #endif 5446 } 5447 /* Interior cell vertices have 4 supports */ 5448 for (c = cStart; c < cEnd; ++c) { 5449 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + c - cStart; 5450 supportRef[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5451 supportRef[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5452 supportRef[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5453 supportRef[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5454 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5455 #if defined(PETSC_USE_DEBUG) 5456 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5457 for (p = 0; p < 4; ++p) { 5458 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", supportRef[p], eStartNew, eEndNew); 5459 } 5460 #endif 5461 } 5462 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5463 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 5464 break; 5465 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 5466 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 5467 cMax = PetscMin(cEnd, cMax); 5468 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 5469 fMax = PetscMin(fEnd, fMax); 5470 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 5471 eMax = PetscMin(eEnd, eMax); 5472 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 5473 /* All cells have 6 faces */ 5474 for (c = cStart; c < cMax; ++c) { 5475 const PetscInt newp = cStartNew + (c - cStart)*4; 5476 const PetscInt *cone, *ornt; 5477 PetscInt coneNew[6]; 5478 PetscInt orntNew[6]; 5479 5480 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5481 #if defined(PETSC_USE_DEBUG) 5482 for (p = 0; p < 4; ++p) { 5483 if (cone[p] >= fMax) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid face %D (fMax %D) in cone position %D for cell %D", cone[p], p, fMax, c); 5484 } 5485 #endif 5486 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5487 /* A hex */ 5488 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 5489 orntNew[0] = ornt[0] < 0 ? -1 : 1; 5490 coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 3; /* T */ 5491 orntNew[1] = -4; 5492 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */ 5493 orntNew[2] = ornt[2] < 0 ? -1 : 1; 5494 coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 0; /* K */ 5495 orntNew[3] = -1; 5496 coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 2; /* R */ 5497 orntNew[4] = 0; 5498 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */ 5499 orntNew[5] = ornt[1] < 0 ? -1 : 1; 5500 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5501 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5502 #if defined(PETSC_USE_DEBUG) 5503 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+0, cStartNew, cEndNew); 5504 for (p = 0; p < 6; ++p) { 5505 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 5506 } 5507 #endif 5508 /* B hex */ 5509 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 5510 orntNew[0] = ornt[0] < 0 ? -2 : 0; 5511 coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 4; /* T */ 5512 orntNew[1] = 0; 5513 coneNew[2] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 0; /* F */ 5514 orntNew[2] = 0; 5515 coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */ 5516 orntNew[3] = ornt[3] < 0 ? -2 : 0; 5517 coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 1; /* R */ 5518 orntNew[4] = 0; 5519 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */ 5520 orntNew[5] = ornt[1] < 0 ? -4 : 2; 5521 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5522 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5523 #if defined(PETSC_USE_DEBUG) 5524 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+1, cStartNew, cEndNew); 5525 for (p = 0; p < 6; ++p) { 5526 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 5527 } 5528 #endif 5529 /* C hex */ 5530 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 5531 orntNew[0] = ornt[0] < 0 ? -4 : 2; 5532 coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 5; /* T */ 5533 orntNew[1] = -4; 5534 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */ 5535 orntNew[2] = ornt[2] < 0 ? -2 : 0; 5536 coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 1; /* K */ 5537 orntNew[3] = -1; 5538 coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */ 5539 orntNew[4] = ornt[3] < 0 ? -1 : 1; 5540 coneNew[5] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 2; /* L */ 5541 orntNew[5] = -4; 5542 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5543 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5544 #if defined(PETSC_USE_DEBUG) 5545 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+2, cStartNew, cEndNew); 5546 for (p = 0; p < 6; ++p) { 5547 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 5548 } 5549 #endif 5550 /* D hex */ 5551 coneNew[0] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 3; /* B */ 5552 orntNew[0] = 0; 5553 coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */ 5554 orntNew[1] = ornt[3] < 0 ? -1 : 1; 5555 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */ 5556 orntNew[2] = ornt[2] < 0 ? -4 : 2; 5557 coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 4; /* K */ 5558 orntNew[3] = -1; 5559 coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 5; /* R */ 5560 orntNew[4] = 0; 5561 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */ 5562 orntNew[5] = ornt[1] < 0 ? -2 : 0; 5563 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 5564 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 5565 #if defined(PETSC_USE_DEBUG) 5566 if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+3, cStartNew, cEndNew); 5567 for (p = 0; p < 6; ++p) { 5568 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 5569 } 5570 #endif 5571 } 5572 for (c = cMax; c < cEnd; ++c) { 5573 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*3; 5574 const PetscInt *cone, *ornt, *fornt; 5575 PetscInt coneNew[6], orntNew[6]; 5576 PetscInt o, of, cf; 5577 5578 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5579 #if defined(PETSC_USE_DEBUG) 5580 if (cone[0] >= fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid face %D (fMax %D) in cone position 0 for cell %D", cone[0], fMax, c); 5581 if (cone[1] >= fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid face %D (fMax %D) in cone position 1 for cell %D", cone[1], fMax, c); 5582 if (cone[2] < fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected face %D (fMax %D) in cone position 2 for cell %D", cone[2], fMax, c); 5583 if (cone[3] < fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected face %D (fMax %D) in cone position 3 for cell %D", cone[3], fMax, c); 5584 if (cone[4] < fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected face %D (fMax %D) in cone position 4 for cell %D", cone[4], fMax, c); 5585 #endif 5586 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5587 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 5588 o = ornt[0] < 0 ? -1 : 1; 5589 /* A hex */ 5590 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 5591 orntNew[0] = ornt[0] < 0 ? -1 : 1; 5592 coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* T */ 5593 orntNew[1] = ornt[1] < 0 ? 1 : -1; 5594 cf = GetTriEdge_Static(ornt[0], 2); 5595 of = fornt[cf] < 0 ? -1 : 1; 5596 coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* F */ 5597 orntNew[2] = o*of < 0 ? 0 : -1; 5598 coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; /* K */ 5599 orntNew[3] = -1; 5600 coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; /* R */ 5601 orntNew[4] = 0; 5602 cf = GetTriEdge_Static(ornt[0], 0); 5603 of = fornt[cf] < 0 ? -1 : 1; 5604 coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* L */ 5605 orntNew[5] = o*of < 0 ? 1 : -4; 5606 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5607 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5608 #if defined(PETSC_USE_DEBUG) 5609 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+0, cStartNew, cEndNew); 5610 for (p = 0; p < 6; ++p) { 5611 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 5612 } 5613 #endif 5614 /* B hex */ 5615 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 5616 orntNew[0] = ornt[0] < 0 ? -2 : 0; 5617 coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* T */ 5618 orntNew[1] = ornt[1] < 0 ? 2 : -4; 5619 coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; /* F */ 5620 orntNew[2] = 0; 5621 cf = GetTriEdge_Static(ornt[0], 1); 5622 of = fornt[cf] < 0 ? -1 : 1; 5623 coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* K */ 5624 orntNew[3] = o*of < 0 ? 0 : -1; 5625 coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; /* R */ 5626 orntNew[4] = -1; 5627 cf = GetTriEdge_Static(ornt[0], 0); 5628 of = fornt[cf] < 0 ? -1 : 1; 5629 coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* L */ 5630 orntNew[5] = o*of < 0 ? 1 : -4; 5631 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5632 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5633 #if defined(PETSC_USE_DEBUG) 5634 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+1, cStartNew, cEndNew); 5635 for (p = 0; p < 6; ++p) { 5636 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 5637 } 5638 #endif 5639 /* C hex */ 5640 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 5641 orntNew[0] = ornt[0] < 0 ? -4 : 2; 5642 coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* T */ 5643 orntNew[1] = ornt[1] < 0 ? 0 : -2; 5644 cf = GetTriEdge_Static(ornt[0], 2); 5645 of = fornt[cf] < 0 ? -1 : 1; 5646 coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* F */ 5647 orntNew[2] = o*of < 0 ? 0 : -1; 5648 coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; /* K */ 5649 orntNew[3] = 0; 5650 cf = GetTriEdge_Static(ornt[0], 1); 5651 of = fornt[cf] < 0 ? -1 : 1; 5652 coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* R */ 5653 orntNew[4] = o*of < 0 ? 0 : -1; 5654 coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; /* L */ 5655 orntNew[5] = -4; 5656 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5657 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5658 #if defined(PETSC_USE_DEBUG) 5659 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+2, cStartNew, cEndNew); 5660 for (p = 0; p < 6; ++p) { 5661 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 5662 } 5663 #endif 5664 } 5665 5666 /* Split faces have 4 edges and the same cells as the parent */ 5667 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5668 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 5669 for (f = fStart; f < fMax; ++f) { 5670 const PetscInt newp = fStartNew + (f - fStart)*3; 5671 const PetscInt *cone, *ornt, *support; 5672 PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s; 5673 5674 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5675 #if defined(PETSC_USE_DEBUG) 5676 for (p = 0; p < 3; ++p) { 5677 if (cone[p] >= eMax) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid edge %D (eMax %D) in cone position %D for face %D", cone[p], p, eMax, f); 5678 } 5679 #endif 5680 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5681 /* A quad */ 5682 coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 5683 orntNew[0] = ornt[2]; 5684 coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 5685 orntNew[1] = ornt[0]; 5686 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 5687 orntNew[2] = 0; 5688 coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 5689 orntNew[3] = -2; 5690 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5691 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5692 #if defined(PETSC_USE_DEBUG) 5693 if ((newp+0 < fStartNew) || (newp+0 >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp+0, fStartNew, fEndNew); 5694 for (p = 0; p < 4; ++p) { 5695 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 5696 } 5697 #endif 5698 /* B quad */ 5699 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 5700 orntNew[0] = ornt[0]; 5701 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 5702 orntNew[1] = ornt[1]; 5703 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 5704 orntNew[2] = 0; 5705 coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 5706 orntNew[3] = -2; 5707 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5708 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5709 #if defined(PETSC_USE_DEBUG) 5710 if ((newp+1 < fStartNew) || (newp+1 >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp+1, fStartNew, fEndNew); 5711 for (p = 0; p < 4; ++p) { 5712 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 5713 } 5714 #endif 5715 /* C quad */ 5716 coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 5717 orntNew[0] = ornt[1]; 5718 coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 5719 orntNew[1] = ornt[2]; 5720 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 5721 orntNew[2] = 0; 5722 coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 5723 orntNew[3] = -2; 5724 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5725 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5726 #if defined(PETSC_USE_DEBUG) 5727 if ((newp+2 < fStartNew) || (newp+2 >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp+2, fStartNew, fEndNew); 5728 for (p = 0; p < 4; ++p) { 5729 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 5730 } 5731 #endif 5732 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5733 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5734 for (r = 0; r < 3; ++r) { 5735 for (s = 0; s < supportSize; ++s) { 5736 PetscInt subf; 5737 5738 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5739 if (coneSize != 5 && support[s] >= cMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax); 5740 if (coneSize != 4 && support[s] < cMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax); 5741 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5742 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5743 for (c = 0; c < coneSize; ++c) { 5744 if (cone[c] == f) break; 5745 } 5746 subf = GetTriSubfaceInverse_Static(ornt[c], r); 5747 if (coneSize == 4) { 5748 supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf]; 5749 } else if (coneSize == 5) { 5750 if (c != 0 && c != 1) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected position %D in cone %D of cell %D (cMax %D) for face %D", c, support[s], cMax, f); 5751 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*3 + subf; 5752 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax); 5753 } 5754 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 5755 #if defined(PETSC_USE_DEBUG) 5756 if ((newp+r < fStartNew) || (newp+r >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp+r, fStartNew, fEndNew); 5757 for (p = 0; p < supportSize; ++p) { 5758 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportRef[p], cStartNew, cEndNew); 5759 } 5760 #endif 5761 } 5762 } 5763 /* Interior faces have 4 edges and 2 cells */ 5764 for (c = cStart; c < cMax; ++c) { 5765 PetscInt newp = fStartNew + (fMax - fStart)*3 + (c - cStart)*6; 5766 const PetscInt *cone, *ornt; 5767 PetscInt coneNew[4], orntNew[4]; 5768 PetscInt supportNew[2]; 5769 5770 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5771 #if defined(PETSC_USE_DEBUG) 5772 for (p = 0; p < 4; ++p) { 5773 if (cone[p] >= fMax) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid face %D (fMax %D) in cone position %D for face %D", cone[p], p, fMax, f); 5774 } 5775 #endif 5776 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5777 /* Face {a, g, m, h} */ 5778 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 5779 orntNew[0] = 0; 5780 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 5781 orntNew[1] = 0; 5782 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 5783 orntNew[2] = -2; 5784 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 5785 orntNew[3] = -2; 5786 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5787 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5788 #if defined(PETSC_USE_DEBUG) 5789 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5790 for (p = 0; p < 4; ++p) { 5791 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 5792 } 5793 #endif 5794 supportNew[0] = cStartNew + (c - cStart)*4 + 0; 5795 supportNew[1] = cStartNew + (c - cStart)*4 + 1; 5796 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5797 #if defined(PETSC_USE_DEBUG) 5798 for (p = 0; p < 2; ++p) { 5799 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 5800 } 5801 #endif 5802 ++newp; 5803 /* Face {g, b, l , m} */ 5804 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 5805 orntNew[0] = -2; 5806 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0); 5807 orntNew[1] = 0; 5808 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 5809 orntNew[2] = 0; 5810 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 5811 orntNew[3] = -2; 5812 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5813 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5814 #if defined(PETSC_USE_DEBUG) 5815 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5816 for (p = 0; p < 4; ++p) { 5817 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 5818 } 5819 #endif 5820 supportNew[0] = cStartNew + (c - cStart)*4 + 1; 5821 supportNew[1] = cStartNew + (c - cStart)*4 + 2; 5822 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5823 #if defined(PETSC_USE_DEBUG) 5824 for (p = 0; p < 2; ++p) { 5825 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 5826 } 5827 #endif 5828 ++newp; 5829 /* Face {c, g, m, i} */ 5830 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 5831 orntNew[0] = 0; 5832 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 5833 orntNew[1] = 0; 5834 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 5835 orntNew[2] = -2; 5836 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0); 5837 orntNew[3] = -2; 5838 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5839 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5840 #if defined(PETSC_USE_DEBUG) 5841 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5842 for (p = 0; p < 4; ++p) { 5843 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 5844 } 5845 #endif 5846 supportNew[0] = cStartNew + (c - cStart)*4 + 0; 5847 supportNew[1] = cStartNew + (c - cStart)*4 + 2; 5848 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5849 #if defined(PETSC_USE_DEBUG) 5850 for (p = 0; p < 2; ++p) { 5851 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 5852 } 5853 #endif 5854 ++newp; 5855 /* Face {d, h, m, i} */ 5856 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 5857 orntNew[0] = 0; 5858 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 5859 orntNew[1] = 0; 5860 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 5861 orntNew[2] = -2; 5862 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2); 5863 orntNew[3] = -2; 5864 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5865 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5866 #if defined(PETSC_USE_DEBUG) 5867 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5868 for (p = 0; p < 4; ++p) { 5869 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 5870 } 5871 #endif 5872 supportNew[0] = cStartNew + (c - cStart)*4 + 0; 5873 supportNew[1] = cStartNew + (c - cStart)*4 + 3; 5874 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5875 #if defined(PETSC_USE_DEBUG) 5876 for (p = 0; p < 2; ++p) { 5877 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 5878 } 5879 #endif 5880 ++newp; 5881 /* Face {h, m, l, e} */ 5882 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 5883 orntNew[0] = 0; 5884 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 5885 orntNew[1] = -2; 5886 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1); 5887 orntNew[2] = -2; 5888 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 5889 orntNew[3] = 0; 5890 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5891 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5892 #if defined(PETSC_USE_DEBUG) 5893 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5894 for (p = 0; p < 4; ++p) { 5895 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 5896 } 5897 #endif 5898 supportNew[0] = cStartNew + (c - cStart)*4 + 1; 5899 supportNew[1] = cStartNew + (c - cStart)*4 + 3; 5900 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5901 #if defined(PETSC_USE_DEBUG) 5902 for (p = 0; p < 2; ++p) { 5903 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 5904 } 5905 #endif 5906 ++newp; 5907 /* Face {i, m, l, f} */ 5908 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 5909 orntNew[0] = 0; 5910 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 5911 orntNew[1] = -2; 5912 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2); 5913 orntNew[2] = -2; 5914 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1); 5915 orntNew[3] = 0; 5916 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5917 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5918 #if defined(PETSC_USE_DEBUG) 5919 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5920 for (p = 0; p < 4; ++p) { 5921 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 5922 } 5923 #endif 5924 supportNew[0] = cStartNew + (c - cStart)*4 + 2; 5925 supportNew[1] = cStartNew + (c - cStart)*4 + 3; 5926 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5927 #if defined(PETSC_USE_DEBUG) 5928 for (p = 0; p < 2; ++p) { 5929 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 5930 } 5931 #endif 5932 ++newp; 5933 } 5934 /* Hybrid split faces have 4 edges and same cells */ 5935 for (f = fMax; f < fEnd; ++f) { 5936 const PetscInt *cone, *ornt, *support; 5937 PetscInt coneNew[4], orntNew[4]; 5938 PetscInt size, s; 5939 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f - fMax)*2; 5940 5941 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5942 #if defined(PETSC_USE_DEBUG) 5943 if (cone[0] >= eMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid edge %D (eMax %D) in cone position 0 for face %D", cone[0], eMax, f); 5944 if (cone[1] >= eMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid edge %D (eMax %D) in cone position 1 for face %D", cone[1], eMax, f); 5945 if (cone[2] < eMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected edge %D (eMax %D) in cone position 2 for face %D", cone[2], eMax, f); 5946 if (cone[3] < eMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected edge %D (eMax %D) in cone position 3 for face %D", cone[3], eMax, f); 5947 #endif 5948 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5949 /* A face */ 5950 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 5951 orntNew[0] = ornt[0]; 5952 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax); 5953 orntNew[1] = 0; 5954 coneNew[2] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 5955 orntNew[2] = ornt[1] < 0 ? 0 : -2; 5956 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (cone[2] - eMax); 5957 orntNew[3] = ornt[2] < 0 ? 0 : -2; 5958 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5959 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5960 #if defined(PETSC_USE_DEBUG) 5961 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5962 for (p = 0; p < 4; ++p) { 5963 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 5964 } 5965 #endif 5966 5967 /* B face */ 5968 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 5969 orntNew[0] = ornt[0]; 5970 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (cone[3] - eMax); 5971 orntNew[1] = ornt[3]; 5972 coneNew[2] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 5973 orntNew[2] = ornt[1] < 0 ? 0 : -2; 5974 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax); 5975 orntNew[3] = -2; 5976 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5977 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5978 #if defined(PETSC_USE_DEBUG) 5979 if ((newp+1 < fStartNew) || (newp+1 >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp+1, fStartNew, fEndNew); 5980 for (p = 0; p < 4; ++p) { 5981 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 5982 } 5983 #endif 5984 5985 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5986 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5987 for (r = 0; r < 2; ++r) { 5988 for (s = 0; s < size; ++s) { 5989 const PetscInt *coneCell, *orntCell, *fornt; 5990 PetscInt coneSize, o, of, c; 5991 5992 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5993 if (coneSize != 5 || support[s] < cMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax); 5994 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 5995 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 5996 o = orntCell[0] < 0 ? -1 : 1; 5997 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 5998 if (c == 0 || c == 1) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected position in cone %D of cell %D (cMax %D) for face %D", c, support[s], cMax, f); 5999 if (c == coneSize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]); 6000 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 6001 of = fornt[c-2] < 0 ? -1 : 1; 6002 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*3 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 6003 } 6004 ierr = DMPlexSetSupport(rdm, newp + r, supportRef);CHKERRQ(ierr); 6005 #if defined(PETSC_USE_DEBUG) 6006 for (p = 0; p < size; ++p) { 6007 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportRef[p], cStartNew, cEndNew); 6008 } 6009 #endif 6010 } 6011 } 6012 /* Interior hybrid faces have 4 edges and 2 cells */ 6013 for (c = cMax; c < cEnd; ++c) { 6014 PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3; 6015 const PetscInt *cone, *ornt; 6016 PetscInt coneNew[4], orntNew[4]; 6017 PetscInt supportNew[2]; 6018 6019 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6020 #if defined(PETSC_USE_DEBUG) 6021 if (cone[0] >= fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid face %D (fMax %D) in cone position 0 for cell %D", cone[0], fMax, c); 6022 if (cone[1] >= fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid face %D (fMax %D) in cone position 1 for cell %D", cone[1], fMax, c); 6023 if (cone[2] < fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected face %D (fMax %D) in cone position 2 for cell %D", cone[2], fMax, c); 6024 if (cone[3] < fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected face %D (fMax %D) in cone position 3 for cell %D", cone[3], fMax, c); 6025 if (cone[4] < fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected face %D (fMax %D) in cone position 3 for cell %D", cone[3], fMax, c); 6026 #endif 6027 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6028 /* Face {a, g, h, d} */ 6029 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 6030 orntNew[0] = 0; 6031 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6032 orntNew[1] = 0; 6033 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 6034 orntNew[2] = -2; 6035 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[2] - fMax); 6036 orntNew[3] = -2; 6037 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6038 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6039 #if defined(PETSC_USE_DEBUG) 6040 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6041 for (p = 0; p < 4; ++p) { 6042 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6043 } 6044 #endif 6045 supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 0; 6046 supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 1; 6047 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6048 #if defined(PETSC_USE_DEBUG) 6049 for (p = 0; p < 2; ++p) { 6050 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 6051 } 6052 #endif 6053 ++newp; 6054 /* Face {b, g, h, l} */ 6055 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 6056 orntNew[0] = 0; 6057 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6058 orntNew[1] = 0; 6059 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 6060 orntNew[2] = -2; 6061 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[3] - fMax); 6062 orntNew[3] = -2; 6063 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6064 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6065 #if defined(PETSC_USE_DEBUG) 6066 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6067 for (p = 0; p < 4; ++p) { 6068 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6069 } 6070 #endif 6071 supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 1; 6072 supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 2; 6073 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6074 #if defined(PETSC_USE_DEBUG) 6075 for (p = 0; p < 2; ++p) { 6076 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 6077 } 6078 #endif 6079 ++newp; 6080 /* Face {c, g, h, f} */ 6081 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 6082 orntNew[0] = 0; 6083 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6084 orntNew[1] = 0; 6085 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 6086 orntNew[2] = -2; 6087 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[4] - fMax); 6088 orntNew[3] = -2; 6089 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6090 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6091 #if defined(PETSC_USE_DEBUG) 6092 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6093 for (p = 0; p < 4; ++p) { 6094 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6095 } 6096 #endif 6097 supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 2; 6098 supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 0; 6099 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6100 #if defined(PETSC_USE_DEBUG) 6101 for (p = 0; p < 2; ++p) { 6102 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 6103 } 6104 #endif 6105 } 6106 /* Face edges have 2 vertices and 2 + cell faces supports */ 6107 for (f = fStart; f < fMax; ++f) { 6108 const PetscInt *cone, *ornt, *support; 6109 PetscInt coneSize, supportSize, s; 6110 6111 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6112 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6113 for (r = 0; r < 3; ++r) { 6114 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 6115 PetscInt coneNew[2]; 6116 PetscInt fint[4][3] = { {0, 1, 2}, 6117 {3, 4, 0}, 6118 {2, 5, 3}, 6119 {1, 4, 5} }; 6120 6121 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6122 if (cone[r] >= eMax) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone point %D in position %D for face %D (eMax %D)", cone[r], r, f, eMax); 6123 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 6124 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + f - fStart; 6125 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6126 #if defined(PETSC_USE_DEBUG) 6127 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6128 for (p = 0; p < 2; ++p) { 6129 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 6130 } 6131 #endif 6132 supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3; 6133 supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3; 6134 for (s = 0; s < supportSize; ++s) { 6135 PetscInt er; 6136 6137 supportRef[2+s] = -1; 6138 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6139 if (coneSize != 5 && support[s] >= cMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax); 6140 if (coneSize != 4 && support[s] < cMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax); 6141 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6142 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6143 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 6144 er = GetTriInteriorEdgeInverse_Static(ornt[c], r); 6145 if (coneSize == 4) { 6146 supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (support[s] - cStart)*6 + fint[c][er]; 6147 } else if (coneSize == 5) { 6148 if (c != 0 && c != 1) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected position %D in cone %D of cell %D (cMax %D) for face %D", c, support[s], cMax, f); 6149 supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + er; 6150 } 6151 } 6152 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6153 #if defined(PETSC_USE_DEBUG) 6154 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6155 for (p = 0; p < supportSize + 2; ++p) { 6156 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 6157 } 6158 #endif 6159 } 6160 } 6161 /* Interior cell edges have 2 vertices and 3 faces */ 6162 for (c = cStart; c < cMax; ++c) { 6163 const PetscInt *cone; 6164 PetscInt fint[4][3] = { {0,1,2}, 6165 {0,3,4}, 6166 {2,3,5}, 6167 {1,4,5} } ; 6168 6169 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6170 for (r = 0; r < 4; r++) { 6171 PetscInt coneNew[2], supportNew[3]; 6172 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + r; 6173 6174 if (cone[r] >= fMax) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid face %D (fMax %D) in cone position %D for cell %D", cone[r], r, fMax, c); 6175 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 6176 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax -fStart) + c - cStart; 6177 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6178 #if defined(PETSC_USE_DEBUG) 6179 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6180 for (p = 0; p < 2; ++p) { 6181 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 6182 } 6183 #endif 6184 supportNew[0] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][0]; 6185 supportNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][1]; 6186 supportNew[2] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][2]; 6187 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6188 #if defined(PETSC_USE_DEBUG) 6189 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6190 for (p = 0; p < 3; ++p) { 6191 if ((supportNew[p] < fStartNew) || (supportNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportNew[p], fStartNew, fEndNew); 6192 } 6193 #endif 6194 } 6195 } 6196 /* Hybrid edges have two vertices and the same faces */ 6197 for (e = eMax; e < eEnd; ++e) { 6198 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (e - eMax); 6199 const PetscInt *cone, *support, *fcone; 6200 PetscInt coneNew[2], size, fsize, s; 6201 6202 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6203 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 6204 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6205 coneNew[0] = vStartNew + (cone[0] - vStart); 6206 coneNew[1] = vStartNew + (cone[1] - vStart); 6207 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6208 #if defined(PETSC_USE_DEBUG) 6209 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is a edge [%D, %D)", newp, eStartNew, eEndNew); 6210 for (p = 0; p < 2; ++p) { 6211 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 6212 } 6213 #endif 6214 for (s = 0; s < size; ++s) { 6215 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 6216 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 6217 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 6218 if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]); 6219 supportRef[s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (support[s] - fMax)*2 + c-2; 6220 } 6221 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6222 #if defined(PETSC_USE_DEBUG) 6223 for (p = 0; p < size; ++p) { 6224 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 6225 } 6226 #endif 6227 } 6228 /* Hybrid face edges have 2 vertices and 2 + cell faces supports */ 6229 for (f = fMax; f < fEnd; ++f) { 6230 const PetscInt *cone, *ornt, *support; 6231 PetscInt coneSize, supportSize; 6232 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + f - fMax; 6233 PetscInt coneNew[2], s; 6234 6235 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6236 #if defined(PETSC_USE_DEBUG) 6237 if (cone[0] >= eMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone point %D in position 0 for face %D (eMax %D)", cone[0], f, eMax); 6238 if (cone[1] >= eMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone point %D in position 1 for face %D (eMax %D)", cone[1], f, eMax); 6239 #endif 6240 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 6241 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 6242 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6243 #if defined(PETSC_USE_DEBUG) 6244 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6245 for (p = 0; p < 2; ++p) { 6246 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 6247 } 6248 #endif 6249 supportRef[0] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f- fMax)*2 + 0; 6250 supportRef[1] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f- fMax)*2 + 1; 6251 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6252 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6253 for (s = 0; s < supportSize; ++s) { 6254 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6255 if (coneSize != 5 || support[s] < cMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax); 6256 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6257 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6258 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 6259 if (c == 0 || c == 1) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected position in cone %D of cell %D (cMax %D) for face %D", c, support[s], cMax, f); 6260 supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c - 2; 6261 } 6262 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6263 #if defined(PETSC_USE_DEBUG) 6264 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6265 for (p = 0; p < supportSize + 2; ++p) { 6266 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 6267 } 6268 #endif 6269 } 6270 /* Hybrid cell edges have 2 vertices and 3 faces */ 6271 for (c = cMax; c < cEnd; ++c) { 6272 PetscInt coneNew[2], supportNew[3]; 6273 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6274 const PetscInt *cone; 6275 6276 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6277 #if defined(PETSC_USE_DEBUG) 6278 if (cone[0] >= fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid face %D (fMax %D) in cone position 0 for cell %D", cone[0], fMax, c); 6279 if (cone[1] >= fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid face %D (fMax %D) in cone position 1 for cell %D", cone[1], fMax, c); 6280 #endif 6281 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 6282 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 6283 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6284 #if defined(PETSC_USE_DEBUG) 6285 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6286 for (p = 0; p < 2; ++p) { 6287 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 6288 } 6289 #endif 6290 supportNew[0] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 6291 supportNew[1] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 6292 supportNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 6293 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6294 #if defined(PETSC_USE_DEBUG) 6295 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6296 for (p = 0; p < 3; ++p) { 6297 if ((supportNew[p] < fStartNew) || (supportNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportNew[p], fStartNew, fEndNew); 6298 } 6299 #endif 6300 } 6301 /* Old vertices have identical supports */ 6302 for (v = vStart; v < vEnd; ++v) { 6303 const PetscInt newp = vStartNew + (v - vStart); 6304 const PetscInt *support, *cone; 6305 PetscInt size, s; 6306 6307 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 6308 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 6309 for (s = 0; s < size; ++s) { 6310 const PetscInt e = support[s]; 6311 6312 supportRef[s] = -1; 6313 if (eStart <= e) { 6314 if (e < eMax) { 6315 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6316 supportRef[s] = eStartNew + (e - eStart)*2 + (cone[1] == v ? 1 : 0); 6317 } else if (e < eEnd) { 6318 supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + e - eMax; 6319 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", e, eStart, eEnd); 6320 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", e, eStart, eEnd); 6321 } 6322 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6323 #if defined(PETSC_USE_DEBUG) 6324 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 6325 for (p = 0; p < size; ++p) { 6326 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", supportRef[p], eStartNew, eEndNew); 6327 } 6328 #endif 6329 } 6330 /* Interior edge vertices have 2 + faces supports */ 6331 for (e = eStart; e < eMax; ++e) { 6332 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 6333 const PetscInt *cone, *support; 6334 PetscInt size, s; 6335 6336 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 6337 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6338 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 6339 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 6340 for (s = 0; s < size; ++s) { 6341 PetscInt r, coneSize; 6342 6343 supportRef[2+s] = -1; 6344 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6345 if (coneSize != 4 && support[s] >= fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax); 6346 if (coneSize != 3 && support[s] < fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax); 6347 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6348 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 6349 if (coneSize == 3) supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + r; 6350 else if (coneSize == 4) { 6351 if (r != 0 && r != 1) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected position in cone %D of face %D (fMax %D) for edge %D", r, support[s], fMax, e); 6352 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + support[s] - fMax; 6353 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax); 6354 } 6355 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6356 #if defined(PETSC_USE_DEBUG) 6357 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 6358 for (p = 0; p < 2+size; ++p) { 6359 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", supportRef[p], eStartNew, eEndNew); 6360 } 6361 #endif 6362 } 6363 /* Split Edges have 2 vertices and the same faces as the parent */ 6364 for (e = eStart; e < eMax; ++e) { 6365 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 6366 6367 for (r = 0; r < 2; ++r) { 6368 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 6369 const PetscInt *cone, *ornt, *support; 6370 PetscInt coneNew[2], coneSize, c, supportSize, s; 6371 6372 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6373 coneNew[0] = vStartNew + (cone[0] - vStart); 6374 coneNew[1] = vStartNew + (cone[1] - vStart); 6375 coneNew[(r+1)%2] = newv; 6376 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6377 #if defined(PETSC_USE_DEBUG) 6378 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6379 for (p = 0; p < 2; ++p) { 6380 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 6381 } 6382 #endif 6383 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 6384 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6385 for (s = 0; s < supportSize; ++s) { 6386 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6387 if (coneSize != 4 && support[s] >= fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax); 6388 if (coneSize != 3 && support[s] < fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax); 6389 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6390 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6391 for (c = 0; c < coneSize; ++c) { 6392 if (cone[c] == e) break; 6393 } 6394 if (coneSize == 3) supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3; 6395 else if (coneSize == 4) { 6396 if (c != 0 && c != 1) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected position in cone %D of face %D (fMax %D) for edge %D", c, support[s], fMax, e); 6397 supportRef[s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 6398 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax); 6399 } 6400 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6401 #if defined(PETSC_USE_DEBUG) 6402 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6403 for (p = 0; p < supportSize; ++p) { 6404 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 6405 } 6406 #endif 6407 } 6408 } 6409 /* Face vertices have 3 + cells supports */ 6410 for (f = fStart; f < fMax; ++f) { 6411 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 6412 const PetscInt *cone, *support; 6413 PetscInt size, s; 6414 6415 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 6416 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6417 supportRef[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 6418 supportRef[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 6419 supportRef[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 6420 for (s = 0; s < size; ++s) { 6421 PetscInt r, coneSize; 6422 6423 supportRef[3+s] = -1; 6424 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6425 if (coneSize != 5 && support[s] >= cMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax); 6426 if (coneSize != 4 && support[s] < cMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax); 6427 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6428 for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;} 6429 if (coneSize == 4) supportRef[3+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (support[s] - cStart)*4 + r; 6430 else if (coneSize == 5) { 6431 if (r != 0 && r != 1) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected position in cone %D of cell %D (cMax %D) for face %D", r, support[s], cMax, f); 6432 supportRef[3+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + support[s] - cMax; 6433 } 6434 } 6435 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6436 #if defined(PETSC_USE_DEBUG) 6437 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 6438 for (p = 0; p < 3+size; ++p) { 6439 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", supportRef[p], eStartNew, eEndNew); 6440 } 6441 #endif 6442 } 6443 /* Interior cell vertices have 4 supports */ 6444 for (c = cStart; c < cMax; ++c) { 6445 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + c - cStart; 6446 6447 supportRef[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 6448 supportRef[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 6449 supportRef[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 6450 supportRef[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 6451 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6452 #if defined(PETSC_USE_DEBUG) 6453 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 6454 for (p = 0; p < 4; ++p) { 6455 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", supportRef[p], eStartNew, eEndNew); 6456 } 6457 #endif 6458 } 6459 ierr = PetscFree(supportRef);CHKERRQ(ierr); 6460 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 6461 break; 6462 case REFINER_HEX_3D: 6463 /* 6464 Bottom (viewed from top) Top 6465 1---------2---------2 7---------2---------6 6466 | | | | | | 6467 | B 2 C | | H 2 G | 6468 | | | | | | 6469 3----3----0----1----1 3----3----0----1----1 6470 | | | | | | 6471 | A 0 D | | E 0 F | 6472 | | | | | | 6473 0---------0---------3 4---------0---------5 6474 */ 6475 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 6476 for (c = cStart; c < cEnd; ++c) { 6477 const PetscInt newp = (c - cStart)*8; 6478 const PetscInt *cone, *ornt; 6479 PetscInt coneNew[6], orntNew[6]; 6480 6481 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6482 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6483 /* A hex */ 6484 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 6485 orntNew[0] = ornt[0]; 6486 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 6487 orntNew[1] = 0; 6488 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 6489 orntNew[2] = ornt[2]; 6490 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 6491 orntNew[3] = 0; 6492 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 6493 orntNew[4] = 0; 6494 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 6495 orntNew[5] = ornt[5]; 6496 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 6497 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 6498 #if defined(PETSC_USE_DEBUG) 6499 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+0, cStartNew, cEndNew); 6500 for (p = 0; p < 6; ++p) { 6501 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 6502 } 6503 #endif 6504 /* B hex */ 6505 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 6506 orntNew[0] = ornt[0]; 6507 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 6508 orntNew[1] = 0; 6509 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 6510 orntNew[2] = -1; 6511 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 6512 orntNew[3] = ornt[3]; 6513 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 6514 orntNew[4] = 0; 6515 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 6516 orntNew[5] = ornt[5]; 6517 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 6518 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 6519 #if defined(PETSC_USE_DEBUG) 6520 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+1, cStartNew, cEndNew); 6521 for (p = 0; p < 6; ++p) { 6522 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 6523 } 6524 #endif 6525 /* C hex */ 6526 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 6527 orntNew[0] = ornt[0]; 6528 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 6529 orntNew[1] = 0; 6530 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 6531 orntNew[2] = -1; 6532 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 6533 orntNew[3] = ornt[3]; 6534 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 6535 orntNew[4] = ornt[4]; 6536 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 6537 orntNew[5] = -4; 6538 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 6539 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 6540 #if defined(PETSC_USE_DEBUG) 6541 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+2, cStartNew, cEndNew); 6542 for (p = 0; p < 6; ++p) { 6543 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 6544 } 6545 #endif 6546 /* D hex */ 6547 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 6548 orntNew[0] = ornt[0]; 6549 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 6550 orntNew[1] = 0; 6551 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 6552 orntNew[2] = ornt[2]; 6553 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 6554 orntNew[3] = 0; 6555 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 6556 orntNew[4] = ornt[4]; 6557 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 6558 orntNew[5] = -4; 6559 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 6560 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 6561 #if defined(PETSC_USE_DEBUG) 6562 if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+3, cStartNew, cEndNew); 6563 for (p = 0; p < 6; ++p) { 6564 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 6565 } 6566 #endif 6567 /* E hex */ 6568 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 6569 orntNew[0] = -4; 6570 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 6571 orntNew[1] = ornt[1]; 6572 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 6573 orntNew[2] = ornt[2]; 6574 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 6575 orntNew[3] = 0; 6576 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 6577 orntNew[4] = -1; 6578 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 6579 orntNew[5] = ornt[5]; 6580 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 6581 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 6582 #if defined(PETSC_USE_DEBUG) 6583 if ((newp+4 < cStartNew) || (newp+4 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+4, cStartNew, cEndNew); 6584 for (p = 0; p < 6; ++p) { 6585 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 6586 } 6587 #endif 6588 /* F hex */ 6589 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 6590 orntNew[0] = -4; 6591 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 6592 orntNew[1] = ornt[1]; 6593 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 6594 orntNew[2] = ornt[2]; 6595 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 6596 orntNew[3] = -1; 6597 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 6598 orntNew[4] = ornt[4]; 6599 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 6600 orntNew[5] = 1; 6601 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 6602 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 6603 #if defined(PETSC_USE_DEBUG) 6604 if ((newp+5 < cStartNew) || (newp+5 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+5, cStartNew, cEndNew); 6605 for (p = 0; p < 6; ++p) { 6606 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 6607 } 6608 #endif 6609 /* G hex */ 6610 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 6611 orntNew[0] = -4; 6612 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 6613 orntNew[1] = ornt[1]; 6614 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 6615 orntNew[2] = 0; 6616 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 6617 orntNew[3] = ornt[3]; 6618 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 6619 orntNew[4] = ornt[4]; 6620 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 6621 orntNew[5] = -3; 6622 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 6623 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 6624 #if defined(PETSC_USE_DEBUG) 6625 if ((newp+6 < cStartNew) || (newp+6 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+6, cStartNew, cEndNew); 6626 for (p = 0; p < 6; ++p) { 6627 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 6628 } 6629 #endif 6630 /* H hex */ 6631 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 6632 orntNew[0] = -4; 6633 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 6634 orntNew[1] = ornt[1]; 6635 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 6636 orntNew[2] = -1; 6637 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 6638 orntNew[3] = ornt[3]; 6639 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 6640 orntNew[4] = 3; 6641 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 6642 orntNew[5] = ornt[5]; 6643 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 6644 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 6645 #if defined(PETSC_USE_DEBUG) 6646 if ((newp+7 < cStartNew) || (newp+7 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+7, cStartNew, cEndNew); 6647 for (p = 0; p < 6; ++p) { 6648 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 6649 } 6650 #endif 6651 } 6652 /* Split faces have 4 edges and the same cells as the parent */ 6653 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 6654 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 6655 for (f = fStart; f < fEnd; ++f) { 6656 for (r = 0; r < 4; ++r) { 6657 /* TODO: This can come from GetFaces_Internal() */ 6658 const PetscInt newCells[24] = {0, 1, 2, 3, 4, 5, 6, 7, 0, 3, 5, 4, 2, 1, 7, 6, 3, 2, 6, 5, 0, 4, 7, 1}; 6659 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 6660 const PetscInt *cone, *ornt, *support; 6661 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 6662 6663 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6664 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 6665 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 6666 orntNew[(r+3)%4] = ornt[(r+3)%4]; 6667 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 6668 orntNew[(r+0)%4] = ornt[r]; 6669 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 6670 orntNew[(r+1)%4] = 0; 6671 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 6672 orntNew[(r+2)%4] = -2; 6673 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6674 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6675 #if defined(PETSC_USE_DEBUG) 6676 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6677 for (p = 0; p < 4; ++p) { 6678 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6679 } 6680 #endif 6681 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6682 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6683 for (s = 0; s < supportSize; ++s) { 6684 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6685 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6686 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6687 for (c = 0; c < coneSize; ++c) { 6688 if (cone[c] == f) break; 6689 } 6690 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 6691 } 6692 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6693 #if defined(PETSC_USE_DEBUG) 6694 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6695 for (p = 0; p < supportSize; ++p) { 6696 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportRef[p], cStartNew, cEndNew); 6697 } 6698 #endif 6699 } 6700 } 6701 /* Interior faces have 4 edges and 2 cells */ 6702 for (c = cStart; c < cEnd; ++c) { 6703 const PetscInt newCells[24] = {0, 3, 2, 3, 1, 2, 0, 1, 4, 5, 5, 6, 6, 7, 4, 7, 0, 4, 3, 5, 2, 6, 1, 7}; 6704 const PetscInt *cone, *ornt; 6705 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 6706 6707 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6708 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6709 /* A-D face */ 6710 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 6711 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 6712 orntNew[0] = 0; 6713 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6714 orntNew[1] = 0; 6715 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6716 orntNew[2] = -2; 6717 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 6718 orntNew[3] = -2; 6719 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6720 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6721 #if defined(PETSC_USE_DEBUG) 6722 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6723 for (p = 0; p < 4; ++p) { 6724 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6725 } 6726 #endif 6727 /* C-D face */ 6728 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 6729 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 6730 orntNew[0] = 0; 6731 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6732 orntNew[1] = 0; 6733 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 6734 orntNew[2] = -2; 6735 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 6736 orntNew[3] = -2; 6737 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6738 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6739 #if defined(PETSC_USE_DEBUG) 6740 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6741 for (p = 0; p < 4; ++p) { 6742 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6743 } 6744 #endif 6745 /* B-C face */ 6746 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 6747 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 6748 orntNew[0] = -2; 6749 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 6750 orntNew[1] = 0; 6751 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 6752 orntNew[2] = 0; 6753 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6754 orntNew[3] = -2; 6755 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6756 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6757 #if defined(PETSC_USE_DEBUG) 6758 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6759 for (p = 0; p < 4; ++p) { 6760 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6761 } 6762 #endif 6763 /* A-B face */ 6764 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 6765 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 6766 orntNew[0] = -2; 6767 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 6768 orntNew[1] = 0; 6769 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6770 orntNew[2] = 0; 6771 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6772 orntNew[3] = -2; 6773 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6774 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6775 #if defined(PETSC_USE_DEBUG) 6776 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6777 for (p = 0; p < 4; ++p) { 6778 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6779 } 6780 #endif 6781 /* E-F face */ 6782 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 6783 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6784 orntNew[0] = -2; 6785 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 6786 orntNew[1] = -2; 6787 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 6788 orntNew[2] = 0; 6789 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6790 orntNew[3] = 0; 6791 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6792 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6793 #if defined(PETSC_USE_DEBUG) 6794 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6795 for (p = 0; p < 4; ++p) { 6796 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6797 } 6798 #endif 6799 /* F-G face */ 6800 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 6801 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 6802 orntNew[0] = -2; 6803 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 6804 orntNew[1] = -2; 6805 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 6806 orntNew[2] = 0; 6807 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6808 orntNew[3] = 0; 6809 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6810 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6811 #if defined(PETSC_USE_DEBUG) 6812 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6813 for (p = 0; p < 4; ++p) { 6814 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6815 } 6816 #endif 6817 /* G-H face */ 6818 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 6819 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 6820 orntNew[0] = -2; 6821 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 6822 orntNew[1] = 0; 6823 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6824 orntNew[2] = 0; 6825 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 6826 orntNew[3] = -2; 6827 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6828 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6829 #if defined(PETSC_USE_DEBUG) 6830 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6831 for (p = 0; p < 4; ++p) { 6832 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6833 } 6834 #endif 6835 /* E-H face */ 6836 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 6837 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6838 orntNew[0] = -2; 6839 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 6840 orntNew[1] = -2; 6841 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 6842 orntNew[2] = 0; 6843 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6844 orntNew[3] = 0; 6845 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6846 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6847 #if defined(PETSC_USE_DEBUG) 6848 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6849 for (p = 0; p < 4; ++p) { 6850 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6851 } 6852 #endif 6853 /* A-E face */ 6854 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 6855 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 6856 orntNew[0] = 0; 6857 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6858 orntNew[1] = 0; 6859 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6860 orntNew[2] = -2; 6861 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 6862 orntNew[3] = -2; 6863 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6864 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6865 #if defined(PETSC_USE_DEBUG) 6866 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6867 for (p = 0; p < 4; ++p) { 6868 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6869 } 6870 #endif 6871 /* D-F face */ 6872 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 6873 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 6874 orntNew[0] = -2; 6875 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 6876 orntNew[1] = 0; 6877 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 6878 orntNew[2] = 0; 6879 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6880 orntNew[3] = -2; 6881 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6882 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6883 #if defined(PETSC_USE_DEBUG) 6884 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6885 for (p = 0; p < 4; ++p) { 6886 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6887 } 6888 #endif 6889 /* C-G face */ 6890 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 6891 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 6892 orntNew[0] = -2; 6893 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 6894 orntNew[1] = -2; 6895 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 6896 orntNew[2] = 0; 6897 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 6898 orntNew[3] = 0; 6899 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6900 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6901 #if defined(PETSC_USE_DEBUG) 6902 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6903 for (p = 0; p < 4; ++p) { 6904 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6905 } 6906 #endif 6907 /* B-H face */ 6908 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 6909 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6910 orntNew[0] = 0; 6911 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 6912 orntNew[1] = -2; 6913 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 6914 orntNew[2] = -2; 6915 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 6916 orntNew[3] = 0; 6917 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6918 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6919 #if defined(PETSC_USE_DEBUG) 6920 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6921 for (p = 0; p < 4; ++p) { 6922 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6923 } 6924 #endif 6925 for (r = 0; r < 12; ++r) { 6926 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 6927 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 6928 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 6929 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6930 #if defined(PETSC_USE_DEBUG) 6931 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6932 for (p = 0; p < 2; ++p) { 6933 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 6934 } 6935 #endif 6936 } 6937 } 6938 /* Split edges have 2 vertices and the same faces as the parent */ 6939 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 6940 for (e = eStart; e < eEnd; ++e) { 6941 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 6942 6943 for (r = 0; r < 2; ++r) { 6944 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 6945 const PetscInt *cone, *ornt, *support; 6946 PetscInt coneNew[2], coneSize, c, supportSize, s; 6947 6948 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6949 coneNew[0] = vStartNew + (cone[0] - vStart); 6950 coneNew[1] = vStartNew + (cone[1] - vStart); 6951 coneNew[(r+1)%2] = newv; 6952 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6953 #if defined(PETSC_USE_DEBUG) 6954 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6955 for (p = 0; p < 2; ++p) { 6956 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 6957 } 6958 #endif 6959 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 6960 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6961 for (s = 0; s < supportSize; ++s) { 6962 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6963 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6964 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6965 for (c = 0; c < coneSize; ++c) { 6966 if (cone[c] == e) break; 6967 } 6968 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 6969 } 6970 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6971 #if defined(PETSC_USE_DEBUG) 6972 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6973 for (p = 0; p < supportSize; ++p) { 6974 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 6975 } 6976 #endif 6977 } 6978 } 6979 /* Face edges have 2 vertices and 2+cells faces */ 6980 for (f = fStart; f < fEnd; ++f) { 6981 const PetscInt newFaces[24] = {3, 2, 1, 0, 4, 5, 6, 7, 0, 9, 4, 8, 2, 11, 6, 10, 1, 10, 5, 9, 8, 7, 11, 3}; 6982 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 6983 const PetscInt *cone, *coneCell, *orntCell, *support; 6984 PetscInt coneNew[2], coneSize, c, supportSize, s; 6985 6986 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6987 for (r = 0; r < 4; ++r) { 6988 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 6989 6990 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 6991 coneNew[1] = newv; 6992 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6993 #if defined(PETSC_USE_DEBUG) 6994 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6995 for (p = 0; p < 2; ++p) { 6996 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 6997 } 6998 #endif 6999 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 7000 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7001 supportRef[0] = fStartNew + (f - fStart)*4 + r; 7002 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 7003 for (s = 0; s < supportSize; ++s) { 7004 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7005 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 7006 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 7007 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 7008 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 7009 } 7010 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7011 #if defined(PETSC_USE_DEBUG) 7012 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7013 for (p = 0; p < 2+supportSize; ++p) { 7014 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 7015 } 7016 #endif 7017 } 7018 } 7019 /* Cell edges have 2 vertices and 4 faces */ 7020 for (c = cStart; c < cEnd; ++c) { 7021 const PetscInt newFaces[24] = {0, 1, 2, 3, 4, 5, 6, 7, 0, 9, 4, 8, 2, 11, 6, 10, 1, 10, 5, 9, 3, 8, 7, 11}; 7022 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 7023 const PetscInt *cone; 7024 PetscInt coneNew[2], supportNew[4]; 7025 7026 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7027 for (r = 0; r < 6; ++r) { 7028 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 7029 7030 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 7031 coneNew[1] = newv; 7032 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7033 #if defined(PETSC_USE_DEBUG) 7034 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7035 for (p = 0; p < 2; ++p) { 7036 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 7037 } 7038 #endif 7039 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 7040 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7041 #if defined(PETSC_USE_DEBUG) 7042 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7043 for (p = 0; p < 4; ++p) { 7044 if ((supportNew[p] < fStartNew) || (supportNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportNew[p], fStartNew, fEndNew); 7045 } 7046 #endif 7047 } 7048 } 7049 /* Old vertices have identical supports */ 7050 for (v = vStart; v < vEnd; ++v) { 7051 const PetscInt newp = vStartNew + (v - vStart); 7052 const PetscInt *support, *cone; 7053 PetscInt size, s; 7054 7055 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 7056 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 7057 for (s = 0; s < size; ++s) { 7058 PetscInt r = 0; 7059 7060 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7061 if (cone[1] == v) r = 1; 7062 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 7063 } 7064 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7065 #if defined(PETSC_USE_DEBUG) 7066 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 7067 for (p = 0; p < size; ++p) { 7068 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", supportRef[p], eStartNew, eEndNew); 7069 } 7070 #endif 7071 } 7072 /* Edge vertices have 2 + faces supports */ 7073 for (e = eStart; e < eEnd; ++e) { 7074 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 7075 const PetscInt *cone, *support; 7076 PetscInt size, s; 7077 7078 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 7079 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 7080 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 7081 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 7082 for (s = 0; s < size; ++s) { 7083 PetscInt r; 7084 7085 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7086 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 7087 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 7088 } 7089 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7090 #if defined(PETSC_USE_DEBUG) 7091 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 7092 for (p = 0; p < 2+size; ++p) { 7093 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", supportRef[p], eStartNew, eEndNew); 7094 } 7095 #endif 7096 } 7097 /* Face vertices have 4 + cells supports */ 7098 for (f = fStart; f < fEnd; ++f) { 7099 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 7100 const PetscInt *cone, *support; 7101 PetscInt size, s; 7102 7103 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 7104 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7105 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 7106 for (s = 0; s < size; ++s) { 7107 PetscInt r; 7108 7109 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7110 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 7111 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 7112 } 7113 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7114 #if defined(PETSC_USE_DEBUG) 7115 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 7116 for (p = 0; p < 4+size; ++p) { 7117 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", supportRef[p], eStartNew, eEndNew); 7118 } 7119 #endif 7120 } 7121 /* Cell vertices have 6 supports */ 7122 for (c = cStart; c < cEnd; ++c) { 7123 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 7124 PetscInt supportNew[6]; 7125 7126 for (r = 0; r < 6; ++r) { 7127 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 7128 } 7129 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7130 } 7131 ierr = PetscFree(supportRef);CHKERRQ(ierr); 7132 break; 7133 case REFINER_HYBRID_HEX_3D: 7134 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 7135 /* 7136 Bottom (viewed from top) Top 7137 1---------2---------2 7---------2---------6 7138 | | | | | | 7139 | B 2 C | | H 2 G | 7140 | | | | | | 7141 3----3----0----1----1 3----3----0----1----1 7142 | | | | | | 7143 | A 0 D | | E 0 F | 7144 | | | | | | 7145 0---------0---------3 4---------0---------5 7146 */ 7147 /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 7148 for (c = cStart; c < cMax; ++c) { 7149 const PetscInt newp = (c - cStart)*8; 7150 const PetscInt *cone, *ornt; 7151 PetscInt coneNew[6], orntNew[6]; 7152 7153 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7154 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7155 /* A hex */ 7156 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 7157 orntNew[0] = ornt[0]; 7158 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 7159 orntNew[1] = 0; 7160 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 7161 orntNew[2] = ornt[2]; 7162 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 7163 orntNew[3] = 0; 7164 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 7165 orntNew[4] = 0; 7166 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 7167 orntNew[5] = ornt[5]; 7168 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 7169 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 7170 #if defined(PETSC_USE_DEBUG) 7171 if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+0, cStartNew, cMaxNew); 7172 for (p = 0; p < 6; ++p) { 7173 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 7174 } 7175 #endif 7176 /* B hex */ 7177 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 7178 orntNew[0] = ornt[0]; 7179 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 7180 orntNew[1] = 0; 7181 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 7182 orntNew[2] = -1; 7183 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 7184 orntNew[3] = ornt[3]; 7185 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 7186 orntNew[4] = 0; 7187 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 7188 orntNew[5] = ornt[5]; 7189 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 7190 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 7191 #if defined(PETSC_USE_DEBUG) 7192 if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+1, cStartNew, cMaxNew); 7193 for (p = 0; p < 6; ++p) { 7194 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 7195 } 7196 #endif 7197 /* C hex */ 7198 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 7199 orntNew[0] = ornt[0]; 7200 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 7201 orntNew[1] = 0; 7202 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 7203 orntNew[2] = -1; 7204 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 7205 orntNew[3] = ornt[3]; 7206 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 7207 orntNew[4] = ornt[4]; 7208 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 7209 orntNew[5] = -4; 7210 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 7211 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 7212 #if defined(PETSC_USE_DEBUG) 7213 if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+2, cStartNew, cMaxNew); 7214 for (p = 0; p < 6; ++p) { 7215 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 7216 } 7217 #endif 7218 /* D hex */ 7219 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 7220 orntNew[0] = ornt[0]; 7221 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 7222 orntNew[1] = 0; 7223 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 7224 orntNew[2] = ornt[2]; 7225 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 7226 orntNew[3] = 0; 7227 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 7228 orntNew[4] = ornt[4]; 7229 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 7230 orntNew[5] = -4; 7231 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 7232 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 7233 #if defined(PETSC_USE_DEBUG) 7234 if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+3, cStartNew, cMaxNew); 7235 for (p = 0; p < 6; ++p) { 7236 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 7237 } 7238 #endif 7239 /* E hex */ 7240 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 7241 orntNew[0] = -4; 7242 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 7243 orntNew[1] = ornt[1]; 7244 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 7245 orntNew[2] = ornt[2]; 7246 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 7247 orntNew[3] = 0; 7248 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 7249 orntNew[4] = -1; 7250 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 7251 orntNew[5] = ornt[5]; 7252 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 7253 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 7254 #if defined(PETSC_USE_DEBUG) 7255 if ((newp+4 < cStartNew) || (newp+4 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+4, cStartNew, cMaxNew); 7256 for (p = 0; p < 6; ++p) { 7257 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 7258 } 7259 #endif 7260 /* F hex */ 7261 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 7262 orntNew[0] = -4; 7263 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 7264 orntNew[1] = ornt[1]; 7265 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 7266 orntNew[2] = ornt[2]; 7267 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 7268 orntNew[3] = -1; 7269 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 7270 orntNew[4] = ornt[4]; 7271 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 7272 orntNew[5] = 1; 7273 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 7274 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 7275 #if defined(PETSC_USE_DEBUG) 7276 if ((newp+5 < cStartNew) || (newp+5 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+5, cStartNew, cMaxNew); 7277 for (p = 0; p < 6; ++p) { 7278 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 7279 } 7280 #endif 7281 /* G hex */ 7282 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 7283 orntNew[0] = -4; 7284 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 7285 orntNew[1] = ornt[1]; 7286 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 7287 orntNew[2] = 0; 7288 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 7289 orntNew[3] = ornt[3]; 7290 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 7291 orntNew[4] = ornt[4]; 7292 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 7293 orntNew[5] = -3; 7294 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 7295 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 7296 #if defined(PETSC_USE_DEBUG) 7297 if ((newp+6 < cStartNew) || (newp+6 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+6, cStartNew, cMaxNew); 7298 for (p = 0; p < 6; ++p) { 7299 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 7300 } 7301 #endif 7302 /* H hex */ 7303 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 7304 orntNew[0] = -4; 7305 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 7306 orntNew[1] = ornt[1]; 7307 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 7308 orntNew[2] = -1; 7309 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 7310 orntNew[3] = ornt[3]; 7311 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 7312 orntNew[4] = 3; 7313 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 7314 orntNew[5] = ornt[5]; 7315 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 7316 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 7317 #if defined(PETSC_USE_DEBUG) 7318 if ((newp+7 < cStartNew) || (newp+7 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp+7, cStartNew, cMaxNew); 7319 for (p = 0; p < 6; ++p) { 7320 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 7321 } 7322 #endif 7323 } 7324 /* Hybrid cells have 6 faces: Front, Back, Sides */ 7325 /* 7326 3---------2---------2 7327 | | | 7328 | D 2 C | 7329 | | | 7330 3----3----0----1----1 7331 | | | 7332 | A 0 B | 7333 | | | 7334 0---------0---------1 7335 */ 7336 for (c = cMax; c < cEnd; ++c) { 7337 const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4; 7338 const PetscInt *cone, *ornt, *fornt; 7339 PetscInt coneNew[6], orntNew[6], o, of, i; 7340 7341 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7342 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7343 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 7344 o = ornt[0] < 0 ? -1 : 1; 7345 for (r = 0; r < 4; ++r) { 7346 PetscInt subfA = GetQuadSubface_Static(ornt[0], r); 7347 PetscInt edgeA = GetQuadEdge_Static(ornt[0], r); 7348 PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4); 7349 if (ornt[0] != ornt[1]) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent ordering for matching ends of hybrid cell %D: %D != %D", c, ornt[0], ornt[1]); 7350 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA; 7351 orntNew[0] = ornt[0]; 7352 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA; 7353 orntNew[1] = ornt[0]; 7354 of = fornt[edgeA] < 0 ? -1 : 1; 7355 i = GetQuadEdgeInverse_Static(ornt[0], r) + 2; 7356 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0); 7357 orntNew[i] = ornt[edgeA]; 7358 i = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2; 7359 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA; 7360 orntNew[i] = 0; 7361 i = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2; 7362 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB; 7363 orntNew[i] = -2; 7364 of = fornt[edgeB] < 0 ? -1 : 1; 7365 i = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2; 7366 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1); 7367 orntNew[i] = ornt[edgeB]; 7368 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 7369 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 7370 #if defined(PETSC_USE_DEBUG) 7371 if ((newp+r < cMaxNew) || (newp+r >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid cell [%D, %D)", newp+r, cMaxNew, cEndNew); 7372 for (p = 0; p < 2; ++p) { 7373 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 7374 } 7375 for (p = 2; p < 6; ++p) { 7376 if ((coneNew[p] < fMaxNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", coneNew[p], fMaxNew, fEndNew); 7377 } 7378 #endif 7379 } 7380 } 7381 /* Interior split faces have 4 edges and the same cells as the parent */ 7382 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 7383 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 7384 for (f = fStart; f < fMax; ++f) { 7385 for (r = 0; r < 4; ++r) { 7386 /* TODO: This can come from GetFaces_Internal() */ 7387 const PetscInt newCells[24] = {0, 1, 2, 3, 4, 5, 6, 7, 0, 3, 5, 4, 2, 1, 7, 6, 3, 2, 6, 5, 0, 4, 7, 1}; 7388 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 7389 const PetscInt *cone, *ornt, *support; 7390 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 7391 7392 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7393 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 7394 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 7395 orntNew[(r+3)%4] = ornt[(r+3)%4]; 7396 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 7397 orntNew[(r+0)%4] = ornt[r]; 7398 coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 7399 orntNew[(r+1)%4] = 0; 7400 coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4; 7401 orntNew[(r+2)%4] = -2; 7402 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7403 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7404 #if defined(PETSC_USE_DEBUG) 7405 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7406 for (p = 0; p < 4; ++p) { 7407 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7408 } 7409 #endif 7410 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 7411 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7412 for (s = 0; s < supportSize; ++s) { 7413 PetscInt subf; 7414 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7415 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7416 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 7417 for (c = 0; c < coneSize; ++c) { 7418 if (cone[c] == f) break; 7419 } 7420 subf = GetQuadSubfaceInverse_Static(ornt[c], r); 7421 if (support[s] < cMax) { 7422 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf]; 7423 } else { 7424 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf; 7425 } 7426 } 7427 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7428 #if defined(PETSC_USE_DEBUG) 7429 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7430 for (p = 0; p < supportSize; ++p) { 7431 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportRef[p], cStartNew, cEndNew); 7432 } 7433 #endif 7434 } 7435 } 7436 /* Interior cell faces have 4 edges and 2 cells */ 7437 for (c = cStart; c < cMax; ++c) { 7438 const PetscInt newCells[24] = {0, 3, 2, 3, 1, 2, 0, 1, 4, 5, 5, 6, 6, 7, 4, 7, 0, 4, 3, 5, 2, 6, 1, 7}; 7439 const PetscInt *cone, *ornt; 7440 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 7441 7442 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7443 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7444 /* A-D face */ 7445 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; 7446 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 7447 orntNew[0] = 0; 7448 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7449 orntNew[1] = 0; 7450 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7451 orntNew[2] = -2; 7452 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 7453 orntNew[3] = -2; 7454 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7455 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7456 #if defined(PETSC_USE_DEBUG) 7457 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7458 for (p = 0; p < 4; ++p) { 7459 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7460 } 7461 #endif 7462 /* C-D face */ 7463 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; 7464 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 7465 orntNew[0] = 0; 7466 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7467 orntNew[1] = 0; 7468 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7469 orntNew[2] = -2; 7470 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 7471 orntNew[3] = -2; 7472 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7473 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7474 #if defined(PETSC_USE_DEBUG) 7475 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7476 for (p = 0; p < 4; ++p) { 7477 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7478 } 7479 #endif 7480 /* B-C face */ 7481 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; 7482 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 7483 orntNew[0] = -2; 7484 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 7485 orntNew[1] = 0; 7486 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7487 orntNew[2] = 0; 7488 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7489 orntNew[3] = -2; 7490 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7491 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7492 #if defined(PETSC_USE_DEBUG) 7493 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7494 for (p = 0; p < 4; ++p) { 7495 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7496 } 7497 #endif 7498 /* A-B face */ 7499 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; 7500 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 7501 orntNew[0] = -2; 7502 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 7503 orntNew[1] = 0; 7504 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7505 orntNew[2] = 0; 7506 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7507 orntNew[3] = -2; 7508 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7509 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7510 #if defined(PETSC_USE_DEBUG) 7511 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7512 for (p = 0; p < 4; ++p) { 7513 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7514 } 7515 #endif 7516 /* E-F face */ 7517 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; 7518 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7519 orntNew[0] = -2; 7520 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 7521 orntNew[1] = -2; 7522 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 7523 orntNew[2] = 0; 7524 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7525 orntNew[3] = 0; 7526 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7527 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7528 #if defined(PETSC_USE_DEBUG) 7529 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7530 for (p = 0; p < 4; ++p) { 7531 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7532 } 7533 #endif 7534 /* F-G face */ 7535 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; 7536 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7537 orntNew[0] = -2; 7538 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 7539 orntNew[1] = -2; 7540 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 7541 orntNew[2] = 0; 7542 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7543 orntNew[3] = 0; 7544 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7545 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7546 #if defined(PETSC_USE_DEBUG) 7547 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7548 for (p = 0; p < 4; ++p) { 7549 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7550 } 7551 #endif 7552 /* G-H face */ 7553 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; 7554 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 7555 orntNew[0] = -2; 7556 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 7557 orntNew[1] = 0; 7558 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7559 orntNew[2] = 0; 7560 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7561 orntNew[3] = -2; 7562 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7563 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7564 #if defined(PETSC_USE_DEBUG) 7565 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7566 for (p = 0; p < 4; ++p) { 7567 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7568 } 7569 #endif 7570 /* E-H face */ 7571 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; 7572 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7573 orntNew[0] = -2; 7574 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 7575 orntNew[1] = -2; 7576 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 7577 orntNew[2] = 0; 7578 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7579 orntNew[3] = 0; 7580 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7581 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7582 #if defined(PETSC_USE_DEBUG) 7583 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7584 for (p = 0; p < 4; ++p) { 7585 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7586 } 7587 #endif 7588 /* A-E face */ 7589 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; 7590 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 7591 orntNew[0] = 0; 7592 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7593 orntNew[1] = 0; 7594 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7595 orntNew[2] = -2; 7596 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 7597 orntNew[3] = -2; 7598 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7599 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7600 #if defined(PETSC_USE_DEBUG) 7601 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7602 for (p = 0; p < 4; ++p) { 7603 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7604 } 7605 #endif 7606 /* D-F face */ 7607 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; 7608 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 7609 orntNew[0] = -2; 7610 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 7611 orntNew[1] = 0; 7612 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7613 orntNew[2] = 0; 7614 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7615 orntNew[3] = -2; 7616 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7617 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7618 #if defined(PETSC_USE_DEBUG) 7619 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7620 for (p = 0; p < 4; ++p) { 7621 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7622 } 7623 #endif 7624 /* C-G face */ 7625 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; 7626 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7627 orntNew[0] = -2; 7628 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 7629 orntNew[1] = -2; 7630 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 7631 orntNew[2] = 0; 7632 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7633 orntNew[3] = 0; 7634 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7635 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7636 #if defined(PETSC_USE_DEBUG) 7637 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7638 for (p = 0; p < 4; ++p) { 7639 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7640 } 7641 #endif 7642 /* B-H face */ 7643 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; 7644 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7645 orntNew[0] = 0; 7646 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7647 orntNew[1] = -2; 7648 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 7649 orntNew[2] = -2; 7650 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 7651 orntNew[3] = 0; 7652 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7653 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7654 #if defined(PETSC_USE_DEBUG) 7655 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7656 for (p = 0; p < 4; ++p) { 7657 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7658 } 7659 #endif 7660 for (r = 0; r < 12; ++r) { 7661 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 7662 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 7663 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 7664 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7665 #if defined(PETSC_USE_DEBUG) 7666 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7667 for (p = 0; p < 2; ++p) { 7668 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cMaxNew); 7669 } 7670 #endif 7671 } 7672 } 7673 /* Hybrid split faces have 4 edges and same cells */ 7674 for (f = fMax; f < fEnd; ++f) { 7675 const PetscInt *cone, *ornt, *support; 7676 PetscInt coneNew[4], orntNew[4]; 7677 PetscInt supportNew[2], size, s, c; 7678 7679 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7680 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 7681 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 7682 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7683 for (r = 0; r < 2; ++r) { 7684 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 7685 7686 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 7687 orntNew[0] = ornt[0]; 7688 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 7689 orntNew[1] = ornt[1]; 7690 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax); 7691 orntNew[2+r] = 0; 7692 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 7693 orntNew[3-r] = 0; 7694 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7695 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7696 #if defined(PETSC_USE_DEBUG) 7697 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 7698 for (p = 0; p < 2; ++p) { 7699 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7700 } 7701 for (p = 2; p < 4; ++p) { 7702 if ((coneNew[p] < eMaxNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", coneNew[p], eMaxNew, eEndNew); 7703 } 7704 #endif 7705 for (s = 0; s < size; ++s) { 7706 const PetscInt *coneCell, *orntCell, *fornt; 7707 PetscInt o, of; 7708 7709 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 7710 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 7711 o = orntCell[0] < 0 ? -1 : 1; 7712 for (c = 2; c < 6; ++c) if (coneCell[c] == f) break; 7713 if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]); 7714 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 7715 of = fornt[c-2] < 0 ? -1 : 1; 7716 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%4; 7717 } 7718 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7719 #if defined(PETSC_USE_DEBUG) 7720 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 7721 for (p = 0; p < size; ++p) { 7722 if ((supportNew[p] < cMaxNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid cell [%D, %D)", supportNew[p], cMaxNew, cEndNew); 7723 } 7724 #endif 7725 } 7726 } 7727 /* Hybrid cell faces have 4 edges and 2 cells */ 7728 for (c = cMax; c < cEnd; ++c) { 7729 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4; 7730 const PetscInt *cone, *ornt; 7731 PetscInt coneNew[4], orntNew[4]; 7732 PetscInt supportNew[2]; 7733 7734 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7735 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7736 for (r = 0; r < 4; ++r) { 7737 #if 0 7738 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r); 7739 orntNew[0] = 0; 7740 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r); 7741 orntNew[1] = 0; 7742 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax); 7743 orntNew[2] = 0; 7744 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 7745 orntNew[3] = 0; 7746 #else 7747 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r; 7748 orntNew[0] = 0; 7749 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r; 7750 orntNew[1] = 0; 7751 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax); 7752 orntNew[2] = 0; 7753 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 7754 orntNew[3] = 0; 7755 #endif 7756 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 7757 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 7758 #if defined(PETSC_USE_DEBUG) 7759 if ((newp+r < fMaxNew) || (newp+r >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp+r, fMaxNew, fEndNew); 7760 for (p = 0; p < 2; ++p) { 7761 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7762 } 7763 for (p = 2; p < 4; ++p) { 7764 if ((coneNew[p] < eMaxNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", coneNew[p], eMaxNew, eEndNew); 7765 } 7766 #endif 7767 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r); 7768 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4); 7769 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 7770 #if defined(PETSC_USE_DEBUG) 7771 if ((newp+r < fMaxNew) || (newp+r >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp+r, fMaxNew, fEndNew); 7772 for (p = 0; p < 2; ++p) { 7773 if ((supportNew[p] < cMaxNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid cell [%D, %D)", supportNew[p], cMaxNew, cEndNew); 7774 } 7775 #endif 7776 } 7777 } 7778 /* Interior split edges have 2 vertices and the same faces as the parent */ 7779 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 7780 for (e = eStart; e < eMax; ++e) { 7781 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 7782 7783 for (r = 0; r < 2; ++r) { 7784 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 7785 const PetscInt *cone, *ornt, *support; 7786 PetscInt coneNew[2], coneSize, c, supportSize, s; 7787 7788 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 7789 coneNew[0] = vStartNew + (cone[0] - vStart); 7790 coneNew[1] = vStartNew + (cone[1] - vStart); 7791 coneNew[(r+1)%2] = newv; 7792 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7793 #if defined(PETSC_USE_DEBUG) 7794 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7795 for (p = 0; p < 2; ++p) { 7796 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 7797 } 7798 #endif 7799 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 7800 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 7801 for (s = 0; s < supportSize; ++s) { 7802 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7803 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7804 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 7805 for (c = 0; c < coneSize; ++c) { 7806 if (cone[c] == e) break; 7807 } 7808 if (support[s] < fMax) { 7809 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4; 7810 } else { 7811 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 7812 } 7813 } 7814 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7815 #if defined(PETSC_USE_DEBUG) 7816 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7817 for (p = 0; p < supportSize; ++p) { 7818 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 7819 } 7820 #endif 7821 } 7822 } 7823 /* Interior face edges have 2 vertices and 2+cells faces */ 7824 for (f = fStart; f < fMax; ++f) { 7825 const PetscInt newFaces[24] = {3, 2, 1, 0, 4, 5, 6, 7, 0, 9, 4, 8, 2, 11, 6, 10, 1, 10, 5, 9, 8, 7, 11, 3}; 7826 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 7827 const PetscInt *cone, *coneCell, *orntCell, *support; 7828 PetscInt coneNew[2], coneSize, c, supportSize, s; 7829 7830 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7831 for (r = 0; r < 4; ++r) { 7832 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 7833 7834 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 7835 coneNew[1] = newv; 7836 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7837 #if defined(PETSC_USE_DEBUG) 7838 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7839 for (p = 0; p < 2; ++p) { 7840 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 7841 } 7842 #endif 7843 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 7844 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7845 supportRef[0] = fStartNew + (f - fStart)*4 + r; 7846 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 7847 for (s = 0; s < supportSize; ++s) { 7848 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7849 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 7850 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 7851 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 7852 if (support[s] < cMax) { 7853 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 7854 } else { 7855 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r; 7856 } 7857 } 7858 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7859 #if defined(PETSC_USE_DEBUG) 7860 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7861 for (p = 0; p < 2+supportSize; ++p) { 7862 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportRef[p], fStartNew, fEndNew); 7863 } 7864 #endif 7865 } 7866 } 7867 /* Interior cell edges have 2 vertices and 4 faces */ 7868 for (c = cStart; c < cMax; ++c) { 7869 const PetscInt newFaces[24] = {0, 1, 2, 3, 4, 5, 6, 7, 0, 9, 4, 8, 2, 11, 6, 10, 1, 10, 5, 9, 3, 8, 7, 11}; 7870 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 7871 const PetscInt *cone; 7872 PetscInt coneNew[2], supportNew[4]; 7873 7874 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7875 for (r = 0; r < 6; ++r) { 7876 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 7877 7878 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 7879 coneNew[1] = newv; 7880 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7881 #if defined(PETSC_USE_DEBUG) 7882 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7883 for (p = 0; p < 2; ++p) { 7884 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 7885 } 7886 #endif 7887 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 7888 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7889 #if defined(PETSC_USE_DEBUG) 7890 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7891 for (p = 0; p < 4; ++p) { 7892 if ((supportNew[p] < fStartNew) || (supportNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", supportNew[p], fStartNew, fMaxNew); 7893 } 7894 #endif 7895 } 7896 } 7897 /* Hybrid edges have two vertices and the same faces */ 7898 for (e = eMax; e < eEnd; ++e) { 7899 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 7900 const PetscInt *cone, *support, *fcone; 7901 PetscInt coneNew[2], size, fsize, s; 7902 7903 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 7904 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 7905 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 7906 coneNew[0] = vStartNew + (cone[0] - vStart); 7907 coneNew[1] = vStartNew + (cone[1] - vStart); 7908 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7909 #if defined(PETSC_USE_DEBUG) 7910 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 7911 for (p = 0; p < 2; ++p) { 7912 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 7913 } 7914 #endif 7915 for (s = 0; s < size; ++s) { 7916 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 7917 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 7918 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 7919 if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]); 7920 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2; 7921 } 7922 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7923 #if defined(PETSC_USE_DEBUG) 7924 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 7925 for (p = 0; p < size; ++p) { 7926 if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", supportRef[p], fMaxNew, fEndNew); 7927 } 7928 #endif 7929 } 7930 /* Hybrid face edges have 2 vertices and 2+cells faces */ 7931 for (f = fMax; f < fEnd; ++f) { 7932 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 7933 const PetscInt *cone, *support, *ccone, *cornt; 7934 PetscInt coneNew[2], size, csize, s; 7935 7936 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7937 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 7938 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7939 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 7940 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 7941 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7942 #if defined(PETSC_USE_DEBUG) 7943 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 7944 for (p = 0; p < 2; ++p) { 7945 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 7946 } 7947 #endif 7948 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0; 7949 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1; 7950 for (s = 0; s < size; ++s) { 7951 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 7952 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 7953 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 7954 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 7955 if ((c < 2) || (c >= csize)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Hybrid face %D is not in cone of hybrid cell %D", f, support[s]); 7956 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2; 7957 } 7958 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7959 #if defined(PETSC_USE_DEBUG) 7960 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 7961 for (p = 0; p < 2+size; ++p) { 7962 if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", supportRef[p], fMaxNew, fEndNew); 7963 } 7964 #endif 7965 } 7966 /* Hybrid cell edges have 2 vertices and 4 faces */ 7967 for (c = cMax; c < cEnd; ++c) { 7968 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 7969 const PetscInt *cone, *support; 7970 PetscInt coneNew[2], size; 7971 7972 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7973 ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr); 7974 ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr); 7975 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 7976 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 7977 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7978 #if defined(PETSC_USE_DEBUG) 7979 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 7980 for (p = 0; p < 2; ++p) { 7981 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 7982 } 7983 #endif 7984 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0; 7985 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1; 7986 supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2; 7987 supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3; 7988 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7989 #if defined(PETSC_USE_DEBUG) 7990 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 7991 for (p = 0; p < 4; ++p) { 7992 if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", supportRef[p], fMaxNew, fEndNew); 7993 } 7994 #endif 7995 } 7996 /* Interior vertices have identical supports */ 7997 for (v = vStart; v < vEnd; ++v) { 7998 const PetscInt newp = vStartNew + (v - vStart); 7999 const PetscInt *support, *cone; 8000 PetscInt size, s; 8001 8002 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 8003 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 8004 for (s = 0; s < size; ++s) { 8005 PetscInt r = 0; 8006 8007 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8008 if (cone[1] == v) r = 1; 8009 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 8010 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax); 8011 } 8012 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8013 #if defined(PETSC_USE_DEBUG) 8014 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 8015 for (p = 0; p < size; ++p) { 8016 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", supportRef[p], eStartNew, eEndNew); 8017 } 8018 #endif 8019 } 8020 /* Interior edge vertices have 2 + faces supports */ 8021 for (e = eStart; e < eMax; ++e) { 8022 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 8023 const PetscInt *cone, *support; 8024 PetscInt size, s; 8025 8026 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 8027 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 8028 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 8029 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 8030 for (s = 0; s < size; ++s) { 8031 PetscInt r; 8032 8033 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8034 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 8035 if (support[s] < fMax) { 8036 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r; 8037 } else { 8038 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax); 8039 } 8040 } 8041 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8042 #if defined(PETSC_USE_DEBUG) 8043 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 8044 for (p = 0; p < 2+size; ++p) { 8045 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", supportRef[p], eStartNew, eEndNew); 8046 } 8047 #endif 8048 } 8049 /* Interior face vertices have 4 + cells supports */ 8050 for (f = fStart; f < fMax; ++f) { 8051 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 8052 const PetscInt *cone, *support; 8053 PetscInt size, s; 8054 8055 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 8056 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 8057 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 8058 for (s = 0; s < size; ++s) { 8059 PetscInt r; 8060 8061 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8062 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 8063 if (support[s] < cMax) { 8064 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r; 8065 } else { 8066 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax); 8067 } 8068 } 8069 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8070 #if defined(PETSC_USE_DEBUG) 8071 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 8072 for (p = 0; p < 4+size; ++p) { 8073 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", supportRef[p], eStartNew, eEndNew); 8074 } 8075 #endif 8076 } 8077 /* Cell vertices have 6 supports */ 8078 for (c = cStart; c < cMax; ++c) { 8079 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 8080 PetscInt supportNew[6]; 8081 8082 for (r = 0; r < 6; ++r) { 8083 supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 8084 } 8085 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 8086 } 8087 ierr = PetscFree(supportRef);CHKERRQ(ierr); 8088 break; 8089 default: 8090 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", refiner); 8091 } 8092 PetscFunctionReturn(0); 8093 } 8094 8095 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 8096 { 8097 PetscSection coordSection, coordSectionNew; 8098 Vec coordinates, coordinatesNew; 8099 PetscScalar *coords, *coordsNew; 8100 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 8101 PetscInt dim, spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax; 8102 PetscInt c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 8103 PetscInt cStartNew, cEndNew, vEndNew, *parentId = NULL; 8104 VecType vtype; 8105 PetscBool isperiodic, localize = PETSC_FALSE, needcoords = PETSC_FALSE; 8106 const PetscReal *maxCell, *L; 8107 const DMBoundaryType *bd; 8108 PetscErrorCode ierr; 8109 8110 PetscFunctionBegin; 8111 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 8112 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 8113 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8114 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 8115 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8116 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 8117 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 8118 if (cMax < 0) cMax = cEnd; 8119 if (fMax < 0) fMax = fEnd; 8120 if (eMax < 0) eMax = eEnd; 8121 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, NULL, NULL, &vStartNew);CHKERRQ(ierr); 8122 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, NULL, NULL, &vEndNew);CHKERRQ(ierr); 8123 ierr = DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);CHKERRQ(ierr); 8124 /* Determine if we need to localize coordinates when generating them */ 8125 if (isperiodic && !maxCell) { 8126 ierr = DMGetCoordinatesLocalized(dm, &localize);CHKERRQ(ierr); 8127 if (!localize) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot refine if coordinates have not been localized"); 8128 } 8129 if (isperiodic) { 8130 ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)dm),((PetscObject)dm)->prefix,"DMPlex coords refinement options","DM");CHKERRQ(ierr); 8131 ierr = PetscOptionsBool("-dm_plex_refine_localize","Automatically localize from parent cells",NULL,localize,&localize,NULL);CHKERRQ(ierr); 8132 ierr = PetscOptionsEnd();CHKERRQ(ierr); 8133 if (localize) { 8134 ierr = DMLocalizeCoordinates(dm);CHKERRQ(ierr); 8135 } 8136 } 8137 ierr = DMSetPeriodicity(rdm, isperiodic, maxCell, L, bd);CHKERRQ(ierr); 8138 8139 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 8140 ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr); 8141 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 8142 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 8143 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr); 8144 8145 if (localize) { 8146 PetscInt p, r, newp, *pi; 8147 8148 /* New coordinates will be already localized on the cell */ 8149 ierr = PetscSectionSetChart(coordSectionNew, 0, vStartNew+numVertices);CHKERRQ(ierr); 8150 8151 /* We need the parentId to properly localize coordinates */ 8152 ierr = PetscMalloc1(cEndNew-cStartNew,&pi);CHKERRQ(ierr); 8153 switch (refiner) { 8154 case REFINER_NOOP: 8155 break; 8156 case REFINER_SIMPLEX_1D: 8157 for (p = cStart; p < cEnd; ++p) { 8158 for (r = 0; r < 2; ++r) { 8159 newp = (p - cStart)*2 + r; 8160 pi[newp] = p; 8161 } 8162 } 8163 break; 8164 case REFINER_SIMPLEX_2D: 8165 for (p = cStart; p < cEnd; ++p) { 8166 for (r = 0; r < 4; ++r) { 8167 newp = (p - cStart)*4 + r; 8168 pi[newp] = p; 8169 } 8170 } 8171 break; 8172 case REFINER_HEX_2D: 8173 for (p = cStart; p < cEnd; ++p) { 8174 for (r = 0; r < 4; ++r) { 8175 newp = (p - cStart)*4 + r; 8176 pi[newp] = p; 8177 } 8178 } 8179 break; 8180 case REFINER_SIMPLEX_TO_HEX_2D: 8181 for (p = cStart; p < cEnd; ++p) { 8182 for (r = 0; r < 3; ++r) { 8183 newp = (p - cStart)*3 + r; 8184 pi[newp] = p; 8185 } 8186 } 8187 break; 8188 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 8189 for (p = cStart; p < cMax; ++p) { 8190 for (r = 0; r < 3; ++r) { 8191 newp = (p - cStart)*3 + r; 8192 pi[newp] = p; 8193 } 8194 } 8195 for (p = cMax; p < cEnd; ++p) { 8196 for (r = 0; r < 4; ++r) { 8197 newp = (cMax - cStart)*3 + (p - cMax)*4 + r; 8198 pi[newp] = p; 8199 } 8200 } 8201 /* The refiner needs midpoint vertices on hybrid edges and hybrid cells */ 8202 cMax = cEnd; 8203 eMax = eEnd; 8204 break; 8205 case REFINER_HYBRID_SIMPLEX_2D: 8206 for (p = cStart; p < cMax; ++p) { 8207 for (r = 0; r < 4; ++r) { 8208 newp = (p - cStart)*4 + r; 8209 pi[newp] = p; 8210 } 8211 } 8212 for (p = cMax; p < cEnd; ++p) { 8213 for (r = 0; r < 2; ++r) { 8214 newp = (cMax - cStart)*4 + (p - cMax)*2 + r; 8215 pi[newp] = p; 8216 } 8217 } 8218 break; 8219 case REFINER_HYBRID_HEX_2D: 8220 for (p = cStart; p < cMax; ++p) { 8221 for (r = 0; r < 4; ++r) { 8222 newp = (p - cStart)*4 + r; 8223 pi[newp] = p; 8224 } 8225 } 8226 for (p = cMax; p < cEnd; ++p) { 8227 for (r = 0; r < 2; ++r) { 8228 newp = (cMax - cStart)*4 + (p - cMax)*2 + r; 8229 pi[newp] = p; 8230 } 8231 } 8232 break; 8233 case REFINER_SIMPLEX_3D: 8234 for (p = cStart; p < cEnd; ++p) { 8235 for (r = 0; r < 8; ++r) { 8236 newp = (p - cStart)*8 + r; 8237 pi[newp] = p; 8238 } 8239 } 8240 break; 8241 case REFINER_HYBRID_SIMPLEX_3D: 8242 for (p = cStart; p < cMax; ++p) { 8243 for (r = 0; r < 8; ++r) { 8244 newp = (p - cStart)*8 + r; 8245 pi[newp] = p; 8246 } 8247 } 8248 for (p = cMax; p < cEnd; ++p) { 8249 for (r = 0; r < 4; ++r) { 8250 newp = (cMax - cStart)*8 + (p - cMax)*4 + r; 8251 pi[newp] = p; 8252 } 8253 } 8254 break; 8255 case REFINER_SIMPLEX_TO_HEX_3D: 8256 for (p = cStart; p < cEnd; ++p) { 8257 for (r = 0; r < 4; ++r) { 8258 newp = (p - cStart)*4 + r; 8259 pi[newp] = p; 8260 } 8261 } 8262 break; 8263 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 8264 for (p = cStart; p < cMax; ++p) { 8265 for (r = 0; r < 4; ++r) { 8266 newp = (p - cStart)*4 + r; 8267 pi[newp] = p; 8268 } 8269 } 8270 for (p = cMax; p < cEnd; ++p) { 8271 for (r = 0; r < 3; ++r) { 8272 newp = (cMax - cStart)*4 + (p - cMax)*3 + r; 8273 pi[newp] = p; 8274 } 8275 } 8276 break; 8277 case REFINER_HEX_3D: 8278 for (p = cStart; p < cEnd; ++p) { 8279 for (r = 0; r < 8; ++r) { 8280 newp = (p - cStart)*8 + r; 8281 pi[newp] = p; 8282 } 8283 } 8284 break; 8285 case REFINER_HYBRID_HEX_3D: 8286 for (p = cStart; p < cMax; ++p) { 8287 for (r = 0; r < 8; ++r) { 8288 newp = (p - cStart)*8 + r; 8289 pi[newp] = p; 8290 } 8291 } 8292 for (p = cMax; p < cEnd; ++p) { 8293 for (r = 0; r < 4; ++r) { 8294 newp = (cMax - cStart)*8 + (p - cMax)*4 + r; 8295 pi[newp] = p; 8296 } 8297 } 8298 break; 8299 default: 8300 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", refiner); 8301 } 8302 parentId = pi; 8303 } else { 8304 /* The refiner needs midpoint vertices on hybrid edges and hybrid cells */ 8305 if (REFINER_HYBRID_SIMPLEX_TO_HEX_2D == refiner) { cMax = cEnd; eMax = eEnd; } 8306 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 8307 } 8308 8309 /* All vertices have the spaceDim coordinates */ 8310 if (localize) { 8311 PetscInt c; 8312 8313 for (c = cStartNew; c < cEndNew; ++c) { 8314 PetscInt *cone = NULL; 8315 PetscInt closureSize, coneSize = 0, p, pdof; 8316 8317 ierr = PetscSectionGetDof(coordSection, parentId[c], &pdof); CHKERRQ(ierr); 8318 if (pdof) { /* localize on all cells that are refinement of a localized parent cell */ 8319 ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8320 for (p = 0; p < closureSize*2; p += 2) { 8321 const PetscInt point = cone[p]; 8322 if ((point >= vStartNew) && (point < vEndNew)) coneSize++; 8323 } 8324 ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8325 ierr = PetscSectionSetDof(coordSectionNew, c, coneSize*spaceDim);CHKERRQ(ierr); 8326 ierr = PetscSectionSetFieldDof(coordSectionNew, c, 0, coneSize*spaceDim);CHKERRQ(ierr); 8327 } 8328 } 8329 } 8330 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 8331 ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr); 8332 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr); 8333 } 8334 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 8335 ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr); 8336 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 8337 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 8338 ierr = VecCreate(PETSC_COMM_SELF, &coordinatesNew);CHKERRQ(ierr); 8339 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 8340 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 8341 ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 8342 ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr); 8343 ierr = VecGetType(coordinates, &vtype);CHKERRQ(ierr); 8344 ierr = VecSetType(coordinatesNew, vtype);CHKERRQ(ierr); 8345 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 8346 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 8347 8348 switch (refiner) { 8349 case REFINER_NOOP: break; 8350 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 8351 case REFINER_SIMPLEX_TO_HEX_3D: 8352 case REFINER_HEX_3D: 8353 case REFINER_HYBRID_HEX_3D: 8354 /* Face vertices have the average of corner coordinates */ 8355 for (f = fStart; f < fMax; ++f) { 8356 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 8357 PetscInt *cone = NULL; 8358 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 8359 8360 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8361 for (p = 0; p < closureSize*2; p += 2) { 8362 const PetscInt point = cone[p]; 8363 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 8364 } 8365 if (localize) { 8366 const PetscInt *support = NULL; 8367 PetscInt *rStar = NULL; 8368 PetscInt supportSize, rStarSize, coff, s, ccoff[8]; 8369 PetscBool cellfound = PETSC_FALSE; 8370 8371 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8372 ierr = DMPlexGetSupportSize(dm,f,&supportSize);CHKERRQ(ierr); 8373 ierr = DMPlexGetSupport(dm,f,&support);CHKERRQ(ierr); 8374 /* Compute average of coordinates for each cell sharing the face */ 8375 for (s = 0; s < supportSize; ++s) { 8376 PetscScalar coordsNewAux[3] = { 0.0, 0.0, 0.0 }; 8377 PetscInt *cellCone = NULL; 8378 PetscInt cellClosureSize, cellConeSize = 0, cdof; 8379 const PetscInt cell = support[s]; 8380 PetscBool copyoff = PETSC_FALSE; 8381 8382 ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8383 for (p = 0; p < cellClosureSize*2; p += 2) { 8384 const PetscInt point = cellCone[p]; 8385 if ((point >= vStart) && (point < vEnd)) cellCone[cellConeSize++] = point; 8386 } 8387 ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr); 8388 if (!cdof) { /* the parent cell does not have localized coordinates */ 8389 cellfound = PETSC_TRUE; 8390 for (v = 0; v < coneSize; ++v) { 8391 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 8392 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] += coords[off[v]+d]; 8393 } 8394 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize; 8395 } else { 8396 ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr); 8397 for (p = 0; p < coneSize; ++p) { 8398 const PetscInt tv = cone[p]; 8399 PetscInt cv, voff; 8400 PetscBool locv = PETSC_TRUE; 8401 8402 for (cv = 0; cv < cellConeSize; ++cv) { 8403 if (cellCone[cv] == tv) { 8404 ccoff[p] = spaceDim*cv + coff; 8405 break; 8406 } 8407 } 8408 if (cv == cellConeSize) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map vertex %D",tv); 8409 8410 ierr = PetscSectionGetOffset(coordSection, cone[p], &voff);CHKERRQ(ierr); 8411 for (d = 0; d < spaceDim; ++d) { 8412 coordsNewAux[d] += coords[ccoff[p]+d]; 8413 if (!cellfound && coords[voff+d] != coords[ccoff[p]+d]) locv = PETSC_FALSE; 8414 } 8415 if (locv && !cellfound) { 8416 cellfound = PETSC_TRUE; 8417 copyoff = PETSC_TRUE; 8418 } 8419 } 8420 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize; 8421 8422 /* Found a valid face for the "vertex" part of the Section (physical space) 8423 i.e., a face that has at least one corner in the physical space */ 8424 if (copyoff) for (p = 0; p < coneSize; ++p) off[p] = ccoff[p]; 8425 } 8426 8427 /* Localize new coordinates on each refined cell */ 8428 for (v = 0; v < rStarSize*2; v += 2) { 8429 if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew) && parentId[rStar[v]-cStartNew] == cell) { 8430 PetscInt *rcone = NULL, rclosureSize, lid, rcdof, rcoff; 8431 const PetscInt rcell = rStar[v]; 8432 8433 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr); 8434 if (!rcdof) continue; 8435 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &rcoff);CHKERRQ(ierr); 8436 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8437 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) { 8438 if (rcone[p] == newv) { 8439 for (d = 0; d < spaceDim; d++) coordsNew[rcoff + lid*spaceDim + d] = coordsNewAux[d]; 8440 break; 8441 } 8442 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++; 8443 } 8444 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8445 if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8446 } 8447 } 8448 ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8449 } 8450 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8451 if (!cellfound) { 8452 /* Could not find a valid face for the vertex part, we will get this vertex later (final reduction) */ 8453 needcoords = PETSC_TRUE; 8454 coneSize = 0; 8455 } 8456 } else { 8457 for (v = 0; v < coneSize; ++v) { 8458 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 8459 } 8460 } 8461 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8462 if (coneSize) { 8463 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 8464 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 8465 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 8466 } else { 8467 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL; 8468 } 8469 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8470 } 8471 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 8472 case REFINER_SIMPLEX_TO_HEX_2D: 8473 case REFINER_HEX_2D: 8474 case REFINER_HYBRID_HEX_2D: 8475 case REFINER_SIMPLEX_1D: 8476 /* Cell vertices have the average of corner coordinates */ 8477 for (c = cStart; c < cMax; ++c) { 8478 const PetscInt newv = vStartNew + (vEnd - vStart) + (dim > 1 ? (eMax - eStart) : 0) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0); 8479 PetscInt *cone = NULL; 8480 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d, cdof = 0; 8481 8482 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8483 for (p = 0; p < closureSize*2; p += 2) { 8484 const PetscInt point = cone[p]; 8485 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 8486 } 8487 if (localize) { 8488 ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr); 8489 } 8490 if (cdof) { 8491 PetscInt coff; 8492 8493 ierr = PetscSectionGetOffset(coordSection, c, &coff);CHKERRQ(ierr); 8494 for (v = 0; v < coneSize; ++v) off[v] = spaceDim*v + coff; 8495 } else { 8496 for (v = 0; v < coneSize; ++v) { 8497 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 8498 } 8499 } 8500 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8501 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 8502 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 8503 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 8504 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8505 8506 /* Localize new coordinates on each refined cell */ 8507 if (cdof) { 8508 PetscInt *rStar = NULL, rStarSize; 8509 8510 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8511 for (v = 0; v < rStarSize*2; v += 2) { 8512 if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew)) { 8513 PetscInt *cone = NULL, closureSize, lid, coff, rc, rcdof; 8514 8515 rc = rStar[v]; 8516 ierr = PetscSectionGetDof(coordSectionNew, rc, &rcdof);CHKERRQ(ierr); 8517 if (!rcdof) continue; 8518 ierr = PetscSectionGetOffset(coordSectionNew, rc, &coff);CHKERRQ(ierr); 8519 ierr = DMPlexGetTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8520 for (p = 0, lid = 0; p < closureSize*2; p += 2) { 8521 if (cone[p] == newv) { 8522 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNew[offnew + d]; 8523 break; 8524 } 8525 if (cone[p] >= vStartNew && cone[p] < vEndNew) lid++; 8526 } 8527 if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8528 ierr = DMPlexRestoreTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8529 } 8530 } 8531 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8532 } 8533 } 8534 case REFINER_SIMPLEX_2D: 8535 case REFINER_HYBRID_SIMPLEX_2D: 8536 case REFINER_SIMPLEX_3D: 8537 case REFINER_HYBRID_SIMPLEX_3D: 8538 /* Edge vertices have the average of endpoint coordinates */ 8539 for (e = eStart; e < eMax; ++e) { 8540 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 8541 const PetscInt *cone; 8542 PetscInt coneSize, offA, offB, offnew, d; 8543 8544 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 8545 if (coneSize != 2) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Edge %D cone should have two vertices, not %D", e, coneSize); 8546 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 8547 if (localize) { 8548 PetscInt coff, toffA = -1, toffB = -1, voffA, voffB; 8549 PetscInt *eStar = NULL, eStarSize; 8550 PetscInt *rStar = NULL, rStarSize; 8551 PetscBool cellfound = PETSC_FALSE; 8552 8553 offA = offB = -1; 8554 ierr = PetscSectionGetOffset(coordSection, cone[0], &voffA);CHKERRQ(ierr); 8555 ierr = PetscSectionGetOffset(coordSection, cone[1], &voffB);CHKERRQ(ierr); 8556 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr); 8557 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8558 for (v = 0; v < eStarSize*2; v += 2) { 8559 if ((eStar[v] >= cStart) && (eStar[v] < cEnd)) { 8560 PetscScalar coordsNewAux[3]; 8561 PetscInt *cellCone = NULL; 8562 PetscInt cellClosureSize, s, cv, cdof; 8563 PetscBool locvA = PETSC_TRUE, locvB = PETSC_TRUE; 8564 const PetscInt cell = eStar[v]; 8565 8566 ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr); 8567 if (!cdof) { 8568 /* Found a valid edge for the "vertex" part of the Section */ 8569 offA = voffA; 8570 offB = voffB; 8571 cellfound = PETSC_TRUE; 8572 } else { 8573 ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr); 8574 ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8575 for (s = 0, cv = 0; s < cellClosureSize*2; s += 2) { 8576 const PetscInt point = cellCone[s]; 8577 if ((point >= vStart) && (point < vEnd)) { 8578 if (point == cone[0]) toffA = spaceDim*cv + coff; 8579 else if (point == cone[1]) toffB = spaceDim*cv + coff; 8580 cv++; 8581 } 8582 } 8583 ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8584 for (d = 0; d < spaceDim; ++d) { 8585 coordsNewAux[d] = 0.5*(coords[toffA+d] + coords[toffB+d]); 8586 if (coords[toffA+d] != coords[voffA+d]) locvA = PETSC_FALSE; 8587 if (coords[toffB+d] != coords[voffB+d]) locvB = PETSC_FALSE; 8588 } 8589 /* Found a valid edge for the "vertex" part of the Section */ 8590 if (!cellfound && (locvA || locvB)) { 8591 cellfound = PETSC_TRUE; 8592 offA = toffA; 8593 offB = toffB; 8594 } 8595 } 8596 8597 /* Localize new coordinates on each refined cell */ 8598 for (s = 0; s < rStarSize*2; s += 2) { 8599 if ((rStar[s] >= cStartNew) && (rStar[s] < cEndNew) && parentId[rStar[s]-cStartNew] == cell) { 8600 PetscInt *rcone = NULL, rclosureSize, lid, p, rcdof; 8601 const PetscInt rcell = rStar[s]; 8602 8603 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr); 8604 if (!rcdof) continue; 8605 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &coff);CHKERRQ(ierr); 8606 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8607 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) { 8608 if (rcone[p] == newv) { 8609 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNewAux[d]; 8610 break; 8611 } 8612 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++; 8613 } 8614 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8615 if (p == rclosureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8616 } 8617 } 8618 } 8619 } 8620 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr); 8621 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8622 if (!cellfound) { 8623 /* Could not find a valid edge for the vertex part, we will get this vertex later (final reduction) */ 8624 needcoords = PETSC_TRUE; 8625 } 8626 } else { 8627 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 8628 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 8629 } 8630 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8631 if (offA != -1 && offB != -1) { 8632 ierr = DMLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr); 8633 for (d = 0; d < spaceDim; ++d) { 8634 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]); 8635 } 8636 } else { 8637 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL; 8638 } 8639 } 8640 /* Old vertices have the same coordinates */ 8641 for (v = vStart; v < vEnd; ++v) { 8642 const PetscInt newv = vStartNew + (v - vStart); 8643 PetscInt off, offnew, d; 8644 8645 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 8646 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8647 for (d = 0; d < spaceDim; ++d) { 8648 coordsNew[offnew+d] = coords[off+d]; 8649 } 8650 8651 /* Localize new coordinates on each refined cell */ 8652 if (localize) { 8653 PetscInt p; 8654 PetscInt *rStar = NULL, rStarSize; 8655 8656 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8657 for (p = 0; p < rStarSize*2; p += 2) { 8658 if ((rStar[p] >= cStartNew) && (rStar[p] < cEndNew)) { 8659 PetscScalar ocoords[3]; 8660 PetscInt *cone = NULL, closureSize, lid, coff, s, oc, cdof; 8661 8662 c = rStar[p]; 8663 oc = parentId[c-cStartNew]; 8664 ierr = PetscSectionGetDof(coordSectionNew, c, &cdof);CHKERRQ(ierr); 8665 if (!cdof) continue; 8666 ierr = PetscSectionGetDof(coordSection, oc, &cdof);CHKERRQ(ierr); 8667 if (!cdof) continue; 8668 ierr = PetscSectionGetOffset(coordSection, oc, &coff);CHKERRQ(ierr); 8669 ierr = DMPlexGetTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8670 for (s = 0, lid = 0; s < closureSize*2; s += 2) { 8671 if (cone[s] == v) { 8672 for (d = 0; d < spaceDim; d++) ocoords[d] = coords[coff + lid*spaceDim + d]; 8673 break; 8674 } 8675 if (cone[s] >= vStart && cone[s] < vEnd) lid++; 8676 } 8677 if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map old vertex %D",v); 8678 ierr = DMPlexRestoreTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8679 8680 ierr = PetscSectionGetOffset(coordSectionNew, c, &coff);CHKERRQ(ierr); 8681 ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8682 for (s = 0, lid = 0; s < closureSize*2; s += 2) { 8683 if (cone[s] == newv) { 8684 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = ocoords[d]; 8685 break; 8686 } 8687 if (cone[s] >= vStartNew && cone[s] < vEndNew) lid++; 8688 } 8689 if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8690 ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8691 } 8692 } 8693 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8694 } 8695 } 8696 break; 8697 default: 8698 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", refiner); 8699 } 8700 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 8701 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 8702 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 8703 8704 /* Final reduction (if needed) if we are localizing */ 8705 if (localize) { 8706 PetscBool gred; 8707 8708 ierr = MPIU_Allreduce(&needcoords, &gred, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)rdm));CHKERRQ(ierr); 8709 if (gred) { 8710 DM cdm; 8711 Vec aux; 8712 PetscSF sf; 8713 const PetscScalar *lArray; 8714 PetscScalar *gArray; 8715 #if defined(PETSC_USE_COMPLEX) 8716 PetscInt i, ln, gn; 8717 PetscReal *lrArray; 8718 PetscReal *grArray; 8719 #endif 8720 8721 ierr = DMGetCoordinateDM(rdm, &cdm);CHKERRQ(ierr); 8722 ierr = DMCreateGlobalVector(cdm, &aux);CHKERRQ(ierr); 8723 ierr = DMGetDefaultSF(cdm, &sf);CHKERRQ(ierr); 8724 ierr = VecGetArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr); 8725 ierr = VecSet(aux, PETSC_MIN_REAL);CHKERRQ(ierr); 8726 ierr = VecGetArray(aux, &gArray);CHKERRQ(ierr); 8727 #if defined(PETSC_USE_COMPLEX) 8728 ierr = VecGetLocalSize(aux, &gn);CHKERRQ(ierr); 8729 ierr = VecGetLocalSize(coordinatesNew, &ln);CHKERRQ(ierr); 8730 ierr = PetscMalloc2(ln,&lrArray,gn,&grArray);CHKERRQ(ierr); 8731 for (i=0;i<ln;i++) lrArray[i] = PetscRealPart(lArray[i]); 8732 for (i=0;i<gn;i++) grArray[i] = PetscRealPart(gArray[i]); 8733 ierr = PetscSFReduceBegin(sf, MPIU_REAL, lrArray, grArray, MPIU_MAX);CHKERRQ(ierr); 8734 ierr = PetscSFReduceEnd(sf, MPIU_REAL, lrArray, grArray, MPIU_MAX);CHKERRQ(ierr); 8735 for (i=0;i<gn;i++) gArray[i] = grArray[i]; 8736 ierr = PetscFree2(lrArray,grArray);CHKERRQ(ierr); 8737 #else 8738 ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr); 8739 ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr); 8740 #endif 8741 ierr = VecRestoreArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr); 8742 ierr = VecRestoreArray(aux, &gArray);CHKERRQ(ierr); 8743 ierr = DMGlobalToLocalBegin(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr); 8744 ierr = DMGlobalToLocalEnd(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr); 8745 ierr = VecDestroy(&aux);CHKERRQ(ierr); 8746 } 8747 } 8748 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 8749 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 8750 ierr = PetscFree(parentId);CHKERRQ(ierr); 8751 PetscFunctionReturn(0); 8752 } 8753 8754 /*@ 8755 DMPlexCreateProcessSF - Create an SF which just has process connectivity 8756 8757 Collective on DM 8758 8759 Input Parameters: 8760 + dm - The DM 8761 - sfPoint - The PetscSF which encodes point connectivity 8762 8763 Output Parameters: 8764 + processRanks - A list of process neighbors, or NULL 8765 - sfProcess - An SF encoding the process connectivity, or NULL 8766 8767 Level: developer 8768 8769 .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF() 8770 @*/ 8771 PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 8772 { 8773 PetscInt numRoots, numLeaves, l; 8774 const PetscInt *localPoints; 8775 const PetscSFNode *remotePoints; 8776 PetscInt *localPointsNew; 8777 PetscSFNode *remotePointsNew; 8778 PetscInt *ranks, *ranksNew; 8779 PetscMPIInt size; 8780 PetscErrorCode ierr; 8781 8782 PetscFunctionBegin; 8783 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8784 PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2); 8785 if (processRanks) {PetscValidPointer(processRanks, 3);} 8786 if (sfProcess) {PetscValidPointer(sfProcess, 4);} 8787 ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr); 8788 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 8789 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 8790 for (l = 0; l < numLeaves; ++l) { 8791 ranks[l] = remotePoints[l].rank; 8792 } 8793 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 8794 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 8795 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 8796 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 8797 for (l = 0; l < numLeaves; ++l) { 8798 ranksNew[l] = ranks[l]; 8799 localPointsNew[l] = l; 8800 remotePointsNew[l].index = 0; 8801 remotePointsNew[l].rank = ranksNew[l]; 8802 } 8803 ierr = PetscFree(ranks);CHKERRQ(ierr); 8804 if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);} 8805 else {ierr = PetscFree(ranksNew);CHKERRQ(ierr);} 8806 if (sfProcess) { 8807 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 8808 ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr); 8809 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 8810 ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 8811 } 8812 PetscFunctionReturn(0); 8813 } 8814 8815 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 8816 { 8817 PetscSF sf, sfNew, sfProcess; 8818 IS processRanks; 8819 MPI_Datatype depthType; 8820 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 8821 const PetscInt *localPoints, *neighbors; 8822 const PetscSFNode *remotePoints; 8823 PetscInt *localPointsNew; 8824 PetscSFNode *remotePointsNew; 8825 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 8826 PetscInt ldepth, depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 8827 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 8828 PetscErrorCode ierr; 8829 8830 PetscFunctionBegin; 8831 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 8832 ierr = DMPlexGetDepth(dm, &ldepth);CHKERRQ(ierr); 8833 ierr = MPIU_Allreduce(&ldepth, &depth, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr); 8834 if ((ldepth >= 0) && (depth != ldepth)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent Plex depth %D != %D", ldepth, depth); 8835 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8836 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 8837 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8838 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 8839 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 8840 cMax = cMax < 0 ? cEnd : cMax; 8841 fMax = fMax < 0 ? fEnd : fMax; 8842 eMax = eMax < 0 ? eEnd : eMax; 8843 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 8844 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 8845 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 8846 /* Calculate size of new SF */ 8847 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 8848 if (numRoots < 0) PetscFunctionReturn(0); 8849 for (l = 0; l < numLeaves; ++l) { 8850 const PetscInt p = localPoints[l]; 8851 8852 switch (refiner) { 8853 case REFINER_SIMPLEX_1D: 8854 if ((p >= vStart) && (p < vEnd)) { 8855 /* Interior vertices stay the same */ 8856 ++numLeavesNew; 8857 } else if ((p >= cStart && p < cMax)) { 8858 /* Interior cells add new cells and interior vertices */ 8859 numLeavesNew += 2 + 1; 8860 } 8861 break; 8862 case REFINER_SIMPLEX_2D: 8863 case REFINER_HYBRID_SIMPLEX_2D: 8864 if ((p >= vStart) && (p < vEnd)) { 8865 /* Interior vertices stay the same */ 8866 ++numLeavesNew; 8867 } else if ((p >= fStart) && (p < fMax)) { 8868 /* Interior faces add new faces and vertex */ 8869 numLeavesNew += 2 + 1; 8870 } else if ((p >= fMax) && (p < fEnd)) { 8871 /* Hybrid faces stay the same */ 8872 ++numLeavesNew; 8873 } else if ((p >= cStart) && (p < cMax)) { 8874 /* Interior cells add new cells and interior faces */ 8875 numLeavesNew += 4 + 3; 8876 } else if ((p >= cMax) && (p < cEnd)) { 8877 /* Hybrid cells add new cells and hybrid face */ 8878 numLeavesNew += 2 + 1; 8879 } 8880 break; 8881 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 8882 case REFINER_SIMPLEX_TO_HEX_2D: 8883 if ((p >= vStart) && (p < vEnd)) { 8884 /* Interior vertices stay the same */ 8885 ++numLeavesNew; 8886 } else if ((p >= fStart) && (p < fEnd)) { 8887 /* Interior faces add new faces and vertex */ 8888 numLeavesNew += 2 + 1; 8889 } else if ((p >= cStart) && (p < cMax)) { 8890 /* Interior cells add new cells, interior faces, and vertex */ 8891 numLeavesNew += 3 + 3 + 1; 8892 } else if ((p >= cMax) && (p < cEnd)) { 8893 /* Hybrid cells add new cells, interior faces, and vertex */ 8894 numLeavesNew += 4 + 4 + 1; 8895 } 8896 break; 8897 case REFINER_HEX_2D: 8898 case REFINER_HYBRID_HEX_2D: 8899 if ((p >= vStart) && (p < vEnd)) { 8900 /* Interior vertices stay the same */ 8901 ++numLeavesNew; 8902 } else if ((p >= fStart) && (p < fMax)) { 8903 /* Interior faces add new faces and vertex */ 8904 numLeavesNew += 2 + 1; 8905 } else if ((p >= fMax) && (p < fEnd)) { 8906 /* Hybrid faces stay the same */ 8907 ++numLeavesNew; 8908 } else if ((p >= cStart) && (p < cMax)) { 8909 /* Interior cells add new cells, interior faces, and vertex */ 8910 numLeavesNew += 4 + 4 + 1; 8911 } else if ((p >= cMax) && (p < cEnd)) { 8912 /* Hybrid cells add new cells and hybrid face */ 8913 numLeavesNew += 2 + 1; 8914 } 8915 break; 8916 case REFINER_SIMPLEX_3D: 8917 case REFINER_HYBRID_SIMPLEX_3D: 8918 if ((p >= vStart) && (p < vEnd)) { 8919 /* Interior vertices stay the same */ 8920 ++numLeavesNew; 8921 } else if ((p >= eStart) && (p < eMax)) { 8922 /* Interior edges add new edges and vertex */ 8923 numLeavesNew += 2 + 1; 8924 } else if ((p >= eMax) && (p < eEnd)) { 8925 /* Hybrid edges stay the same */ 8926 ++numLeavesNew; 8927 } else if ((p >= fStart) && (p < fMax)) { 8928 /* Interior faces add new faces and edges */ 8929 numLeavesNew += 4 + 3; 8930 } else if ((p >= fMax) && (p < fEnd)) { 8931 /* Hybrid faces add new faces and edges */ 8932 numLeavesNew += 2 + 1; 8933 } else if ((p >= cStart) && (p < cMax)) { 8934 /* Interior cells add new cells, faces, and edges */ 8935 numLeavesNew += 8 + 8 + 1; 8936 } else if ((p >= cMax) && (p < cEnd)) { 8937 /* Hybrid cells add new cells and faces */ 8938 numLeavesNew += 4 + 3; 8939 } 8940 break; 8941 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 8942 case REFINER_SIMPLEX_TO_HEX_3D: 8943 if ((p >= vStart) && (p < vEnd)) { 8944 /* Interior vertices stay the same */ 8945 ++numLeavesNew; 8946 } else if ((p >= eStart) && (p < eMax)) { 8947 /* Interior edges add new edges and vertex */ 8948 numLeavesNew += 2 + 1; 8949 } else if ((p >= eMax) && (p < eEnd)) { 8950 /* Hybrid edges stay the same */ 8951 ++numLeavesNew; 8952 } else if ((p >= fStart) && (p < fMax)) { 8953 /* Interior faces add new faces, edges and a vertex */ 8954 numLeavesNew += 3 + 3 + 1; 8955 } else if ((p >= fMax) && (p < fEnd)) { 8956 /* Hybrid faces add new faces and an edge */ 8957 numLeavesNew += 2 + 1; 8958 } else if ((p >= cStart) && (p < cMax)) { 8959 /* Interior cells add new cells, faces, edges and a vertex */ 8960 numLeavesNew += 4 + 6 + 4 + 1; 8961 } else if ((p >= cMax) && (p < cEnd)) { 8962 /* Hybrid cells add new cells, faces and an edge */ 8963 numLeavesNew += 3 + 3 + 1; 8964 } 8965 break; 8966 case REFINER_HEX_3D: 8967 case REFINER_HYBRID_HEX_3D: 8968 if ((p >= vStart) && (p < vEnd)) { 8969 /* Old vertices stay the same */ 8970 ++numLeavesNew; 8971 } else if ((p >= eStart) && (p < eMax)) { 8972 /* Interior edges add new edges, and vertex */ 8973 numLeavesNew += 2 + 1; 8974 } else if ((p >= eMax) && (p < eEnd)) { 8975 /* Hybrid edges stay the same */ 8976 ++numLeavesNew; 8977 } else if ((p >= fStart) && (p < fMax)) { 8978 /* Interior faces add new faces, edges, and vertex */ 8979 numLeavesNew += 4 + 4 + 1; 8980 } else if ((p >= fMax) && (p < fEnd)) { 8981 /* Hybrid faces add new faces and edges */ 8982 numLeavesNew += 2 + 1; 8983 } else if ((p >= cStart) && (p < cMax)) { 8984 /* Interior cells add new cells, faces, edges, and vertex */ 8985 numLeavesNew += 8 + 12 + 6 + 1; 8986 } else if ((p >= cStart) && (p < cEnd)) { 8987 /* Hybrid cells add new cells, faces, and edges */ 8988 numLeavesNew += 4 + 4 + 1; 8989 } 8990 break; 8991 default: 8992 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", refiner); 8993 } 8994 } 8995 /* Communicate depthSizes for each remote rank */ 8996 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 8997 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 8998 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 8999 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 9000 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 9001 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 9002 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 9003 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 9004 for (n = 0; n < numNeighbors; ++n) { 9005 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 9006 } 9007 depthSizeOld[depth] = cMax; 9008 depthSizeOld[0] = vMax; 9009 depthSizeOld[depth-1] = fMax; 9010 depthSizeOld[1] = eMax; 9011 9012 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 9013 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 9014 9015 depthSizeOld[depth] = cEnd - cStart; 9016 depthSizeOld[0] = vEnd - vStart; 9017 depthSizeOld[depth-1] = fEnd - fStart; 9018 depthSizeOld[1] = eEnd - eStart; 9019 9020 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 9021 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 9022 for (n = 0; n < numNeighbors; ++n) { 9023 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 9024 rdepthMaxOld[n*(depth+1)+depth] = rdepthMaxOld[n*(depth+1)+depth] < 0 ? rdepthSizeOld[n*(depth+1)+depth] +rcStart[n]: rdepthMaxOld[n*(depth+1)+depth]; 9025 rdepthMaxOld[n*(depth+1)+depth-1] = rdepthMaxOld[n*(depth+1)+depth-1] < 0 ? rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n]: rdepthMaxOld[n*(depth+1)+depth-1]; 9026 rdepthMaxOld[n*(depth+1)+1] = rdepthMaxOld[n*(depth+1)+1] < 0 ? rdepthSizeOld[n*(depth+1)+1] +reStart[n]: rdepthMaxOld[n*(depth+1)+1]; 9027 } 9028 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 9029 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 9030 /* Calculate new point SF */ 9031 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 9032 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 9033 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 9034 for (l = 0, m = 0; l < numLeaves; ++l) { 9035 PetscInt p = localPoints[l]; 9036 PetscInt rp = remotePoints[l].index, n; 9037 PetscMPIInt rrank = remotePoints[l].rank; 9038 9039 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 9040 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %D", rrank); 9041 switch (refiner) { 9042 case REFINER_SIMPLEX_1D: 9043 if ((p >= vStart) && (p < vEnd)) { 9044 /* Old vertices stay the same */ 9045 localPointsNew[m] = vStartNew + (p - vStart); 9046 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9047 remotePointsNew[m].rank = rrank; 9048 ++m; 9049 } else if ((p >= cStart) && (p < cMax)) { 9050 /* Old interior cells add new cells and vertex */ 9051 for (r = 0; r < 2; ++r, ++m) { 9052 localPointsNew[m] = cStartNew + (p - cStart)*2 + r; 9053 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r; 9054 remotePointsNew[m].rank = rrank; 9055 } 9056 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - cStart); 9057 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]); 9058 remotePointsNew[m].rank = rrank; 9059 ++m; 9060 } 9061 break; 9062 case REFINER_SIMPLEX_2D: 9063 case REFINER_HYBRID_SIMPLEX_2D: 9064 if ((p >= vStart) && (p < vEnd)) { 9065 /* Old vertices stay the same */ 9066 localPointsNew[m] = vStartNew + (p - vStart); 9067 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9068 remotePointsNew[m].rank = rrank; 9069 ++m; 9070 } else if ((p >= fStart) && (p < fMax)) { 9071 /* Old interior faces add new faces and vertex */ 9072 for (r = 0; r < 2; ++r, ++m) { 9073 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 9074 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 9075 remotePointsNew[m].rank = rrank; 9076 } 9077 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 9078 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 9079 remotePointsNew[m].rank = rrank; 9080 ++m; 9081 } else if ((p >= fMax) && (p < fEnd)) { 9082 /* Old hybrid faces stay the same */ 9083 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 9084 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 9085 remotePointsNew[m].rank = rrank; 9086 ++m; 9087 } else if ((p >= cStart) && (p < cMax)) { 9088 /* Old interior cells add new cells and interior faces */ 9089 for (r = 0; r < 4; ++r, ++m) { 9090 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9091 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9092 remotePointsNew[m].rank = rrank; 9093 } 9094 for (r = 0; r < 3; ++r, ++m) { 9095 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 9096 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 9097 remotePointsNew[m].rank = rrank; 9098 } 9099 } else if ((p >= cMax) && (p < cEnd)) { 9100 /* Old hybrid cells add new cells and hybrid face */ 9101 for (r = 0; r < 2; ++r, ++m) { 9102 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9103 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9104 remotePointsNew[m].rank = rrank; 9105 } 9106 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 9107 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]); 9108 remotePointsNew[m].rank = rrank; 9109 ++m; 9110 } 9111 break; 9112 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9113 case REFINER_SIMPLEX_TO_HEX_2D: 9114 if ((p >= vStart) && (p < vEnd)) { 9115 /* Old vertices stay the same */ 9116 localPointsNew[m] = vStartNew + (p - vStart); 9117 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9118 remotePointsNew[m].rank = rrank; 9119 ++m; 9120 } else if ((p >= fStart) && (p < fEnd)) { 9121 /* Old interior faces add new faces and vertex */ 9122 for (r = 0; r < 2; ++r, ++m) { 9123 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 9124 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 9125 remotePointsNew[m].rank = rrank; 9126 } 9127 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 9128 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 9129 remotePointsNew[m].rank = rrank; 9130 ++m; 9131 } else if ((p >= cStart) && (p < cMax)) { 9132 /* Old interior cells add new cells, interior faces, and a vertex */ 9133 for (r = 0; r < 3; ++r, ++m) { 9134 localPointsNew[m] = cStartNew + (p - cStart)*3 + r; 9135 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*3 + r; 9136 remotePointsNew[m].rank = rrank; 9137 } 9138 for (r = 0; r < 3; ++r, ++m) { 9139 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9140 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 9141 remotePointsNew[m].rank = rrank; 9142 } 9143 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9144 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 9145 remotePointsNew[m].rank = rrank; 9146 ++m; 9147 } else if ((p >= cMax) && (p < cEnd)) { 9148 /* Old interior hybrid cells add new cells, interior faces, and a vertex */ 9149 for (r = 0; r < 4; ++r, ++m) { 9150 localPointsNew[m] = cStartNew + (cMax - cStart)*3 + (p - cMax)*4 + r; 9151 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*3 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9152 remotePointsNew[m].rank = rrank; 9153 } 9154 for (r = 0; r < 4; ++r, ++m) { 9155 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (p - cMax)*4 + r; 9156 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*3 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9157 remotePointsNew[m].rank = rrank; 9158 } 9159 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9160 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 9161 remotePointsNew[m].rank = rrank; 9162 ++m; 9163 } 9164 break; 9165 case REFINER_HEX_2D: 9166 case REFINER_HYBRID_HEX_2D: 9167 if ((p >= vStart) && (p < vEnd)) { 9168 /* Old vertices stay the same */ 9169 localPointsNew[m] = vStartNew + (p - vStart); 9170 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9171 remotePointsNew[m].rank = rrank; 9172 ++m; 9173 } else if ((p >= fStart) && (p < fMax)) { 9174 /* Old interior faces add new faces and vertex */ 9175 for (r = 0; r < 2; ++r, ++m) { 9176 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 9177 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 9178 remotePointsNew[m].rank = rrank; 9179 } 9180 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 9181 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 9182 remotePointsNew[m].rank = rrank; 9183 ++m; 9184 } else if ((p >= fMax) && (p < fEnd)) { 9185 /* Old hybrid faces stay the same */ 9186 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 9187 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 9188 remotePointsNew[m].rank = rrank; 9189 ++m; 9190 } else if ((p >= cStart) && (p < cMax)) { 9191 /* Old interior cells add new cells, interior faces, and vertex */ 9192 for (r = 0; r < 4; ++r, ++m) { 9193 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9194 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9195 remotePointsNew[m].rank = rrank; 9196 } 9197 for (r = 0; r < 4; ++r, ++m) { 9198 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r; 9199 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r; 9200 remotePointsNew[m].rank = rrank; 9201 } 9202 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (p - cStart); 9203 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]); 9204 remotePointsNew[m].rank = rrank; 9205 ++m; 9206 } else if ((p >= cStart) && (p < cMax)) { 9207 /* Old hybrid cells add new cells and hybrid face */ 9208 for (r = 0; r < 2; ++r, ++m) { 9209 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; /* TODO: is this a bug? */ 9210 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; /* TODO: is this a bug? */ 9211 remotePointsNew[m].rank = rrank; 9212 } 9213 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 9214 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*4 + (rp - rdepthMaxOld[n*(depth+1)+depth]); 9215 remotePointsNew[m].rank = rrank; 9216 ++m; 9217 } 9218 break; 9219 case REFINER_SIMPLEX_3D: 9220 case REFINER_HYBRID_SIMPLEX_3D: 9221 if ((p >= vStart) && (p < vEnd)) { 9222 /* Interior vertices stay the same */ 9223 localPointsNew[m] = vStartNew + (p - vStart); 9224 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9225 remotePointsNew[m].rank = rrank; 9226 ++m; 9227 } else if ((p >= eStart) && (p < eMax)) { 9228 /* Interior edges add new edges and vertex */ 9229 for (r = 0; r < 2; ++r, ++m) { 9230 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 9231 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 9232 remotePointsNew[m].rank = rrank; 9233 } 9234 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 9235 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 9236 remotePointsNew[m].rank = rrank; 9237 ++m; 9238 } else if ((p >= eMax) && (p < eEnd)) { 9239 /* Hybrid edges stay the same */ 9240 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 9241 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*3 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n]) + (rp - rdepthMaxOld[n*(depth+1)+1]); 9242 remotePointsNew[m].rank = rrank; 9243 ++m; 9244 } else if ((p >= fStart) && (p < fMax)) { 9245 /* Interior faces add new faces and edges */ 9246 for (r = 0; r < 4; ++r, ++m) { 9247 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 9248 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 9249 remotePointsNew[m].rank = rrank; 9250 } 9251 for (r = 0; r < 3; ++r, ++m) { 9252 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9253 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 9254 remotePointsNew[m].rank = rrank; 9255 } 9256 } else if ((p >= fMax) && (p < fEnd)) { 9257 /* Hybrid faces add new faces and edges */ 9258 for (r = 0; r < 2; ++r, ++m) { 9259 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 9260 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth-1])*2 + r; 9261 remotePointsNew[m].rank = rrank; 9262 } 9263 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax); 9264 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*3 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n]) + (rdepthSizeOld[n*(depth+1)+1]+reStart[n] - rdepthMaxOld[n*(depth+1)+1]) + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 9265 remotePointsNew[m].rank = rrank; 9266 ++m; 9267 } else if ((p >= cStart) && (p < cMax)) { 9268 /* Interior cells add new cells, faces, and edges */ 9269 for (r = 0; r < 8; ++r, ++m) { 9270 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 9271 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 9272 remotePointsNew[m].rank = rrank; 9273 } 9274 for (r = 0; r < 8; ++r, ++m) { 9275 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 9276 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 9277 remotePointsNew[m].rank = rrank; 9278 } 9279 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + 0; 9280 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*3 + (rp - rcStart[n])*1 + 0; 9281 remotePointsNew[m].rank = rrank; 9282 ++m; 9283 } else if ((p >= cMax) && (p < cEnd)) { 9284 /* Hybrid cells add new cells and faces */ 9285 for (r = 0; r < 4; ++r, ++m) { 9286 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 9287 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9288 remotePointsNew[m].rank = rrank; 9289 } 9290 for (r = 0; r < 3; ++r, ++m) { 9291 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 9292 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth])*3 + r; 9293 remotePointsNew[m].rank = rrank; 9294 } 9295 } 9296 break; 9297 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9298 case REFINER_SIMPLEX_TO_HEX_3D: 9299 if ((p >= vStart) && (p < vEnd)) { 9300 /* Interior vertices stay the same */ 9301 localPointsNew[m] = vStartNew + (p - vStart); 9302 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9303 remotePointsNew[m].rank = rrank; 9304 ++m; 9305 } else if ((p >= eStart) && (p < eMax)) { 9306 /* Interior edges add new edges and vertex */ 9307 for (r = 0; r < 2; ++r, ++m) { 9308 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 9309 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 9310 remotePointsNew[m].rank = rrank; 9311 } 9312 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 9313 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 9314 remotePointsNew[m].rank = rrank; 9315 ++m; 9316 } else if ((p >= eMax) && (p < eEnd)) { 9317 /* Hybrid edges stay the same */ 9318 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (p - eMax); 9319 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*3 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*4 + (rp - rdepthMaxOld[n*(depth+1)+1]); 9320 remotePointsNew[m].rank = rrank; 9321 ++m; 9322 } else if ((p >= fStart) && (p < fMax)) { 9323 /* Interior faces add new faces, edges and a vertex */ 9324 for (r = 0; r < 3; ++r, ++m) { 9325 localPointsNew[m] = fStartNew + (p - fStart)*3 + r; 9326 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*3 + r; 9327 remotePointsNew[m].rank = rrank; 9328 } 9329 for (r = 0; r < 3; ++r, ++m) { 9330 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9331 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 9332 remotePointsNew[m].rank = rrank; 9333 } 9334 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 9335 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 9336 remotePointsNew[m].rank = rrank; 9337 ++m; 9338 } else if ((p >= fMax) && (p < fEnd)) { 9339 /* Interior hybrid faces add new faces and an edge */ 9340 for (r = 0; r < 2; ++r, ++m) { 9341 localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (p - fMax)*2 + r; 9342 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1]- rfStart[n])*3 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rp - rdepthMaxOld[n*(depth+1)+depth-1])*2 + r; 9343 remotePointsNew[m].rank = rrank; 9344 } 9345 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (p - fMax); 9346 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1]- rfStart[n])*3 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*4 + (rdepthSizeOld[n*(depth+1)+1]+reStart[n] - rdepthMaxOld[n*(depth+1)+1]) + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 9347 remotePointsNew[m].rank = rrank; 9348 ++m; 9349 } else if ((p >= cStart) && (p < cMax)) { 9350 /* Interior cells add new cells, faces, edges, and a vertex */ 9351 for (r = 0; r < 4; ++r, ++m) { 9352 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9353 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9354 remotePointsNew[m].rank = rrank; 9355 } 9356 for (r = 0; r < 6; ++r, ++m) { 9357 localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (p - cStart)*6 + r; 9358 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1]- rfStart[n])*3 + (rp - rcStart[n])*6 + r; 9359 remotePointsNew[m].rank = rrank; 9360 } 9361 for (r = 0; r < 4; ++r, ++m) { 9362 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*4 + r; 9363 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1]- reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1]- rfStart[n])*3 + (rp - rcStart[n])*4 + r; 9364 remotePointsNew[m].rank = rrank; 9365 } 9366 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 9367 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1]- reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1]- rfStart[n]) + (rp - rcStart[n]); 9368 remotePointsNew[m].rank = rrank; 9369 ++m; 9370 } else if ((p >= cMax) && (p < cEnd)) { 9371 /* Interior hybrid cells add new cells, faces and an edge */ 9372 for (r = 0; r < 3; ++r, ++m) { 9373 localPointsNew[m] = cStartNew + (cMax - cStart)*4 + (p - cMax)*3 + r; 9374 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*4 + (rp - rdepthMaxOld[n*(depth+1)+depth])*3 + r; 9375 remotePointsNew[m].rank = rrank; 9376 } 9377 for (r = 0; r < 3; ++r, ++m) { 9378 localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 9379 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1]- rfStart[n])*3 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth])*3 + r; 9380 remotePointsNew[m].rank = rrank; 9381 } 9382 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 9383 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1]- reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1]- rfStart[n])*3 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*4 + (rdepthSizeOld[n*(depth+1)+1]+reStart[n] - rdepthMaxOld[n*(depth+1)+1]) + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1]) + (rp - rdepthMaxOld[n*(depth+1)+depth]); 9384 remotePointsNew[m].rank = rrank; 9385 ++m; 9386 } 9387 break; 9388 case REFINER_HEX_3D: 9389 case REFINER_HYBRID_HEX_3D: 9390 if ((p >= vStart) && (p < vEnd)) { 9391 /* Interior vertices stay the same */ 9392 localPointsNew[m] = vStartNew + (p - vStart); 9393 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9394 remotePointsNew[m].rank = rrank; 9395 ++m; 9396 } else if ((p >= eStart) && (p < eMax)) { 9397 /* Interior edges add new edges and vertex */ 9398 for (r = 0; r < 2; ++r, ++m) { 9399 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 9400 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 9401 remotePointsNew[m].rank = rrank; 9402 } 9403 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 9404 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 9405 remotePointsNew[m].rank = rrank; 9406 ++m; 9407 } else if ((p >= eMax) && (p < eEnd)) { 9408 /* Hybrid edges stay the same */ 9409 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 9410 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rp - rdepthMaxOld[n*(depth+1)+1]); 9411 remotePointsNew[m].rank = rrank; 9412 ++m; 9413 } else if ((p >= fStart) && (p < fMax)) { 9414 /* Interior faces add new faces, edges, and vertex */ 9415 for (r = 0; r < 4; ++r, ++m) { 9416 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 9417 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 9418 remotePointsNew[m].rank = rrank; 9419 } 9420 for (r = 0; r < 4; ++r, ++m) { 9421 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 9422 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 9423 remotePointsNew[m].rank = rrank; 9424 } 9425 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 9426 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 9427 remotePointsNew[m].rank = rrank; 9428 ++m; 9429 } else if ((p >= fMax) && (p < fEnd)) { 9430 /* Hybrid faces add new faces and edges */ 9431 for (r = 0; r < 2; ++r, ++m) { 9432 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 9433 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*12 + (rp - rdepthMaxOld[n*(depth+1)+depth-1])*2 + r; 9434 remotePointsNew[m].rank = rrank; 9435 } 9436 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (p - fMax); 9437 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rdepthSizeOld[n*(depth+1)+1]+reStart[n] - rdepthMaxOld[n*(depth+1)+1]) + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 9438 remotePointsNew[m].rank = rrank; 9439 ++m; 9440 } else if ((p >= cStart) && (p < cMax)) { 9441 /* Interior cells add new cells, faces, edges, and vertex */ 9442 for (r = 0; r < 8; ++r, ++m) { 9443 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 9444 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 9445 remotePointsNew[m].rank = rrank; 9446 } 9447 for (r = 0; r < 12; ++r, ++m) { 9448 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 9449 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 9450 remotePointsNew[m].rank = rrank; 9451 } 9452 for (r = 0; r < 6; ++r, ++m) { 9453 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 9454 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*6 + r; 9455 remotePointsNew[m].rank = rrank; 9456 } 9457 for (r = 0; r < 1; ++r, ++m) { 9458 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 9459 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 9460 remotePointsNew[m].rank = rrank; 9461 } 9462 } else if ((p >= cMax) && (p < cEnd)) { 9463 /* Hybrid cells add new cells, faces, and edges */ 9464 for (r = 0; r < 4; ++r, ++m) { 9465 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 9466 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9467 remotePointsNew[m].rank = rrank; 9468 } 9469 for (r = 0; r < 4; ++r, ++m) { 9470 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 9471 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*12 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9472 remotePointsNew[m].rank = rrank; 9473 } 9474 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 9475 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rdepthSizeOld[n*(depth+1)+1]+reStart[n] - rdepthMaxOld[n*(depth+1)+1]) + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1]) + (rp - rdepthMaxOld[n*(depth+1)+depth]); 9476 remotePointsNew[m].rank = rrank; 9477 ++m; 9478 } 9479 break; 9480 default: 9481 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", refiner); 9482 } 9483 } 9484 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %D should be %D", m, numLeavesNew); 9485 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 9486 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 9487 { 9488 PetscSFNode *rp, *rtmp; 9489 PetscInt *lp, *idx, *ltmp, i; 9490 9491 /* SF needs sorted leaves to correct calculate Gather */ 9492 ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr); 9493 ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 9494 ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 9495 for (i = 0; i < numLeavesNew; ++i) { 9496 if ((localPointsNew[i] < pStartNew) || (localPointsNew[i] >= pEndNew)) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Local SF point %D (%D) not in [%D, %D)", localPointsNew[i], i, pStartNew, pEndNew); 9497 idx[i] = i; 9498 } 9499 ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 9500 for (i = 0; i < numLeavesNew; ++i) { 9501 lp[i] = localPointsNew[idx[i]]; 9502 rp[i] = remotePointsNew[idx[i]]; 9503 } 9504 ltmp = localPointsNew; 9505 localPointsNew = lp; 9506 rtmp = remotePointsNew; 9507 remotePointsNew = rp; 9508 ierr = PetscFree(idx);CHKERRQ(ierr); 9509 ierr = PetscFree(ltmp);CHKERRQ(ierr); 9510 ierr = PetscFree(rtmp);CHKERRQ(ierr); 9511 } 9512 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 9513 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 9514 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 9515 PetscFunctionReturn(0); 9516 } 9517 9518 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 9519 { 9520 PetscInt numLabels, l; 9521 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 9522 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 9523 PetscErrorCode ierr; 9524 9525 PetscFunctionBegin; 9526 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 9527 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 9528 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 9529 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 9530 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 9531 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 9532 ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 9533 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 9534 switch (refiner) { 9535 case REFINER_NOOP: 9536 case REFINER_SIMPLEX_1D: 9537 case REFINER_SIMPLEX_2D: 9538 case REFINER_SIMPLEX_TO_HEX_2D: 9539 case REFINER_HEX_2D: 9540 case REFINER_SIMPLEX_3D: 9541 case REFINER_HEX_3D: 9542 case REFINER_SIMPLEX_TO_HEX_3D: 9543 break; 9544 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9545 case REFINER_HYBRID_SIMPLEX_3D: 9546 case REFINER_HYBRID_HEX_3D: 9547 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 9548 case REFINER_HYBRID_SIMPLEX_2D: 9549 case REFINER_HYBRID_HEX_2D: 9550 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 9551 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9552 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 9553 break; 9554 default: 9555 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", refiner); 9556 } 9557 cMax = cMax < 0 ? cEnd : cMax; 9558 fMax = fMax < 0 ? fEnd : fMax; 9559 eMax = eMax < 0 ? eEnd : eMax; 9560 for (l = 0; l < numLabels; ++l) { 9561 DMLabel label, labelNew; 9562 const char *lname; 9563 PetscBool isDepth; 9564 IS valueIS; 9565 const PetscInt *values; 9566 PetscInt defVal; 9567 PetscInt numValues, val; 9568 9569 ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr); 9570 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 9571 if (isDepth) continue; 9572 ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr); 9573 ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr); 9574 ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 9575 ierr = DMLabelGetDefaultValue(label,&defVal);CHKERRQ(ierr); 9576 ierr = DMLabelSetDefaultValue(labelNew,defVal);CHKERRQ(ierr); 9577 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 9578 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 9579 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 9580 for (val = 0; val < numValues; ++val) { 9581 IS pointIS; 9582 const PetscInt *points; 9583 PetscInt numPoints, n; 9584 9585 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 9586 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 9587 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 9588 /* Ensure refined label is created with same number of strata as 9589 * original (even if no entries here). */ 9590 ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr); 9591 for (n = 0; n < numPoints; ++n) { 9592 const PetscInt p = points[n]; 9593 switch (refiner) { 9594 case REFINER_SIMPLEX_1D: 9595 if ((p >= vStart) && (p < vEnd)) { 9596 /* Old vertices stay the same */ 9597 newp = vStartNew + (p - vStart); 9598 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9599 } else if ((p >= cStart) && (p < cEnd)) { 9600 /* Old cells add new cells and vertex */ 9601 newp = vStartNew + (vEnd - vStart) + (p - cStart); 9602 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9603 for (r = 0; r < 2; ++r) { 9604 newp = cStartNew + (p - cStart)*2 + r; 9605 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9606 } 9607 } 9608 break; 9609 case REFINER_SIMPLEX_2D: 9610 if ((p >= vStart) && (p < vEnd)) { 9611 /* Old vertices stay the same */ 9612 newp = vStartNew + (p - vStart); 9613 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9614 } else if ((p >= fStart) && (p < fEnd)) { 9615 /* Old faces add new faces and vertex */ 9616 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9617 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9618 for (r = 0; r < 2; ++r) { 9619 newp = fStartNew + (p - fStart)*2 + r; 9620 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9621 } 9622 } else if ((p >= cStart) && (p < cEnd)) { 9623 /* Old cells add new cells and interior faces */ 9624 for (r = 0; r < 4; ++r) { 9625 newp = cStartNew + (p - cStart)*4 + r; 9626 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9627 } 9628 for (r = 0; r < 3; ++r) { 9629 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9630 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9631 } 9632 } 9633 break; 9634 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9635 case REFINER_SIMPLEX_TO_HEX_2D: 9636 if ((p >= vStart) && (p < vEnd)) { 9637 /* Old vertices stay the same */ 9638 newp = vStartNew + (p - vStart); 9639 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9640 } else if ((p >= fStart) && (p < fEnd)) { 9641 /* Old faces add new faces and vertex */ 9642 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9643 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9644 for (r = 0; r < 2; ++r) { 9645 newp = fStartNew + (p - fStart)*2 + r; 9646 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9647 } 9648 } else if ((p >= cStart) && (p < cMax)) { 9649 /* Old cells add new cells, interior faces, and a vertex */ 9650 for (r = 0; r < 3; ++r) { 9651 newp = cStartNew + (p - cStart)*3 + r; 9652 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9653 } 9654 for (r = 0; r < 3; ++r) { 9655 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9656 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9657 } 9658 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p; 9659 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9660 } else if ((p >= cMax) && (p < cEnd)) { 9661 /* Old hybrid cells add new cells, interior faces, and a vertex */ 9662 for (r = 0; r < 4; ++r) { 9663 newp = cStartNew + (cMax - cStart)*3 + (p - cMax)*4 + r; 9664 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9665 } 9666 for (r = 0; r < 4; ++r) { 9667 newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (p - cMax)*4 + r; 9668 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9669 } 9670 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p; 9671 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9672 } 9673 break; 9674 case REFINER_HEX_2D: 9675 if ((p >= vStart) && (p < vEnd)) { 9676 /* Old vertices stay the same */ 9677 newp = vStartNew + (p - vStart); 9678 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9679 } else if ((p >= fStart) && (p < fEnd)) { 9680 /* Old faces add new faces and vertex */ 9681 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9682 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9683 for (r = 0; r < 2; ++r) { 9684 newp = fStartNew + (p - fStart)*2 + r; 9685 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9686 } 9687 } else if ((p >= cStart) && (p < cEnd)) { 9688 /* Old cells add new cells and interior faces and vertex */ 9689 for (r = 0; r < 4; ++r) { 9690 newp = cStartNew + (p - cStart)*4 + r; 9691 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9692 } 9693 for (r = 0; r < 4; ++r) { 9694 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 9695 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9696 } 9697 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9698 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9699 } 9700 break; 9701 case REFINER_HYBRID_SIMPLEX_2D: 9702 if ((p >= vStart) && (p < vEnd)) { 9703 /* Old vertices stay the same */ 9704 newp = vStartNew + (p - vStart); 9705 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9706 } else if ((p >= fStart) && (p < fMax)) { 9707 /* Old interior faces add new faces and vertex */ 9708 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9709 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9710 for (r = 0; r < 2; ++r) { 9711 newp = fStartNew + (p - fStart)*2 + r; 9712 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9713 } 9714 } else if ((p >= fMax) && (p < fEnd)) { 9715 /* Old hybrid faces stay the same */ 9716 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 9717 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9718 } else if ((p >= cStart) && (p < cMax)) { 9719 /* Old interior cells add new cells and interior faces */ 9720 for (r = 0; r < 4; ++r) { 9721 newp = cStartNew + (p - cStart)*4 + r; 9722 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9723 } 9724 for (r = 0; r < 3; ++r) { 9725 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9726 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9727 } 9728 } else if ((p >= cMax) && (p < cEnd)) { 9729 /* Old hybrid cells add new cells and hybrid face */ 9730 for (r = 0; r < 2; ++r) { 9731 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 9732 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9733 } 9734 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 9735 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9736 } 9737 break; 9738 case REFINER_HYBRID_HEX_2D: 9739 if ((p >= vStart) && (p < vEnd)) { 9740 /* Old vertices stay the same */ 9741 newp = vStartNew + (p - vStart); 9742 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9743 } else if ((p >= fStart) && (p < fMax)) { 9744 /* Old interior faces add new faces and vertex */ 9745 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9746 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9747 for (r = 0; r < 2; ++r) { 9748 newp = fStartNew + (p - fStart)*2 + r; 9749 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9750 } 9751 } else if ((p >= fMax) && (p < fEnd)) { 9752 /* Old hybrid faces stay the same */ 9753 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 9754 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9755 } else if ((p >= cStart) && (p < cMax)) { 9756 /* Old interior cells add new cells, interior faces, and vertex */ 9757 for (r = 0; r < 4; ++r) { 9758 newp = cStartNew + (p - cStart)*4 + r; 9759 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9760 } 9761 for (r = 0; r < 4; ++r) { 9762 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 9763 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9764 } 9765 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9766 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9767 } else if ((p >= cMax) && (p < cEnd)) { 9768 /* Old hybrid cells add new cells and hybrid face */ 9769 for (r = 0; r < 2; ++r) { 9770 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 9771 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9772 } 9773 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 9774 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9775 } 9776 break; 9777 case REFINER_SIMPLEX_3D: 9778 if ((p >= vStart) && (p < vEnd)) { 9779 /* Old vertices stay the same */ 9780 newp = vStartNew + (p - vStart); 9781 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9782 } else if ((p >= eStart) && (p < eEnd)) { 9783 /* Old edges add new edges and vertex */ 9784 for (r = 0; r < 2; ++r) { 9785 newp = eStartNew + (p - eStart)*2 + r; 9786 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9787 } 9788 newp = vStartNew + (vEnd - vStart) + (p - eStart); 9789 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9790 } else if ((p >= fStart) && (p < fEnd)) { 9791 /* Old faces add new faces and edges */ 9792 for (r = 0; r < 4; ++r) { 9793 newp = fStartNew + (p - fStart)*4 + r; 9794 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9795 } 9796 for (r = 0; r < 3; ++r) { 9797 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 9798 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9799 } 9800 } else if ((p >= cStart) && (p < cEnd)) { 9801 /* Old cells add new cells and interior faces and edges */ 9802 for (r = 0; r < 8; ++r) { 9803 newp = cStartNew + (p - cStart)*8 + r; 9804 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9805 } 9806 for (r = 0; r < 8; ++r) { 9807 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 9808 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9809 } 9810 for (r = 0; r < 1; ++r) { 9811 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 9812 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9813 } 9814 } 9815 break; 9816 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9817 case REFINER_SIMPLEX_TO_HEX_3D: 9818 if ((p >= vStart) && (p < vEnd)) { 9819 /* Old vertices stay the same */ 9820 newp = vStartNew + (p - vStart); 9821 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9822 } else if ((p >= eStart) && (p < eMax)) { 9823 /* Interior edges add new edges and vertex */ 9824 for (r = 0; r < 2; ++r) { 9825 newp = eStartNew + (p - eStart)*2 + r; 9826 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9827 } 9828 newp = vStartNew + (vEnd - vStart) + (p - eStart); 9829 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9830 } else if ((p >= eMax) && (p < eEnd)) { 9831 /* Hybrid edges stay the same */ 9832 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + p - eMax; 9833 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9834 } else if ((p >= fStart) && (p < fMax)) { 9835 /* Old faces add new faces, edges and a vertex */ 9836 for (r = 0; r < 3; ++r) { 9837 newp = fStartNew + (p - fStart)*3 + r; 9838 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9839 } 9840 for (r = 0; r < 3; ++r) { 9841 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9842 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9843 } 9844 } else if ((p >= fMax) && (p < fEnd)) { 9845 /* Old hybrid faces add new faces and an edge */ 9846 for (r = 0; r < 2; ++r) { 9847 newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (p - fMax)*2 + r; 9848 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9849 } 9850 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (p - fMax); 9851 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9852 } else if ((p >= cStart) && (p < cMax)) { 9853 /* Old cells add new cells and interior faces and edges and a vertex */ 9854 for (r = 0; r < 4; ++r) { 9855 newp = cStartNew + (p - cStart)*4 + r; 9856 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9857 } 9858 for (r = 0; r < 6; ++r) { 9859 newp = fStartNew + (fMax - fStart)*3 + (p - cStart)*6 + r; 9860 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9861 } 9862 for (r = 0; r < 4; ++r) { 9863 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*4 + r; 9864 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9865 } 9866 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + p - cStart; 9867 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9868 } else if ((p >= cMax) && (p < cEnd)) { 9869 /* Old hybrid cells add new cells and interior faces and an edge */ 9870 for (r = 0; r < 3; ++r) { 9871 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*3 + r; 9872 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9873 } 9874 for (r = 0; r < 3; ++r) { 9875 newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 9876 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9877 } 9878 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + p - cMax; 9879 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9880 } 9881 break; 9882 case REFINER_HYBRID_SIMPLEX_3D: 9883 if ((p >= vStart) && (p < vEnd)) { 9884 /* Interior vertices stay the same */ 9885 newp = vStartNew + (p - vStart); 9886 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9887 } else if ((p >= eStart) && (p < eMax)) { 9888 /* Interior edges add new edges and vertex */ 9889 for (r = 0; r < 2; ++r) { 9890 newp = eStartNew + (p - eStart)*2 + r; 9891 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9892 } 9893 newp = vStartNew + (vEnd - vStart) + (p - eStart); 9894 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9895 } else if ((p >= eMax) && (p < eEnd)) { 9896 /* Hybrid edges stay the same */ 9897 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 9898 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9899 } else if ((p >= fStart) && (p < fMax)) { 9900 /* Interior faces add new faces and edges */ 9901 for (r = 0; r < 4; ++r) { 9902 newp = fStartNew + (p - fStart)*4 + r; 9903 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9904 } 9905 for (r = 0; r < 3; ++r) { 9906 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9907 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9908 } 9909 } else if ((p >= fMax) && (p < fEnd)) { 9910 /* Hybrid faces add new faces and edges */ 9911 for (r = 0; r < 2; ++r) { 9912 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 9913 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9914 } 9915 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 9916 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9917 } else if ((p >= cStart) && (p < cMax)) { 9918 /* Interior cells add new cells, faces, and edges */ 9919 for (r = 0; r < 8; ++r) { 9920 newp = cStartNew + (p - cStart)*8 + r; 9921 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9922 } 9923 for (r = 0; r < 8; ++r) { 9924 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 9925 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9926 } 9927 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 9928 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9929 } else if ((p >= cMax) && (p < cEnd)) { 9930 /* Hybrid cells add new cells and faces */ 9931 for (r = 0; r < 4; ++r) { 9932 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 9933 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9934 } 9935 for (r = 0; r < 3; ++r) { 9936 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 9937 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9938 } 9939 } 9940 break; 9941 case REFINER_HEX_3D: 9942 if ((p >= vStart) && (p < vEnd)) { 9943 /* Old vertices stay the same */ 9944 newp = vStartNew + (p - vStart); 9945 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9946 } else if ((p >= eStart) && (p < eEnd)) { 9947 /* Old edges add new edges and vertex */ 9948 for (r = 0; r < 2; ++r) { 9949 newp = eStartNew + (p - eStart)*2 + r; 9950 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9951 } 9952 newp = vStartNew + (vEnd - vStart) + (p - eStart); 9953 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9954 } else if ((p >= fStart) && (p < fEnd)) { 9955 /* Old faces add new faces, edges, and vertex */ 9956 for (r = 0; r < 4; ++r) { 9957 newp = fStartNew + (p - fStart)*4 + r; 9958 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9959 } 9960 for (r = 0; r < 4; ++r) { 9961 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 9962 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9963 } 9964 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 9965 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9966 } else if ((p >= cStart) && (p < cEnd)) { 9967 /* Old cells add new cells, faces, edges, and vertex */ 9968 for (r = 0; r < 8; ++r) { 9969 newp = cStartNew + (p - cStart)*8 + r; 9970 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9971 } 9972 for (r = 0; r < 12; ++r) { 9973 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 9974 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9975 } 9976 for (r = 0; r < 6; ++r) { 9977 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 9978 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9979 } 9980 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 9981 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9982 } 9983 break; 9984 case REFINER_HYBRID_HEX_3D: 9985 if ((p >= vStart) && (p < vEnd)) { 9986 /* Interior vertices stay the same */ 9987 newp = vStartNew + (p - vStart); 9988 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9989 } else if ((p >= eStart) && (p < eMax)) { 9990 /* Interior edges add new edges and vertex */ 9991 for (r = 0; r < 2; ++r) { 9992 newp = eStartNew + (p - eStart)*2 + r; 9993 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9994 } 9995 newp = vStartNew + (vEnd - vStart) + (p - eStart); 9996 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9997 } else if ((p >= eMax) && (p < eEnd)) { 9998 /* Hybrid edges stay the same */ 9999 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 10000 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10001 } else if ((p >= fStart) && (p < fMax)) { 10002 /* Interior faces add new faces, edges, and vertex */ 10003 for (r = 0; r < 4; ++r) { 10004 newp = fStartNew + (p - fStart)*4 + r; 10005 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10006 } 10007 for (r = 0; r < 4; ++r) { 10008 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 10009 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10010 } 10011 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 10012 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10013 } else if ((p >= fMax) && (p < fEnd)) { 10014 /* Hybrid faces add new faces and edges */ 10015 for (r = 0; r < 2; ++r) { 10016 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 10017 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10018 } 10019 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 10020 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10021 } else if ((p >= cStart) && (p < cMax)) { 10022 /* Interior cells add new cells, faces, edges, and vertex */ 10023 for (r = 0; r < 8; ++r) { 10024 newp = cStartNew + (p - cStart)*8 + r; 10025 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10026 } 10027 for (r = 0; r < 12; ++r) { 10028 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 10029 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10030 } 10031 for (r = 0; r < 6; ++r) { 10032 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 10033 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10034 } 10035 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 10036 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10037 } else if ((p >= cMax) && (p < cEnd)) { 10038 /* Hybrid cells add new cells, faces, and edges */ 10039 for (r = 0; r < 4; ++r) { 10040 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 10041 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10042 } 10043 for (r = 0; r < 4; ++r) { 10044 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 10045 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10046 } 10047 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 10048 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10049 } 10050 break; 10051 default: 10052 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", refiner); 10053 } 10054 } 10055 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 10056 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 10057 } 10058 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 10059 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 10060 if (0) { 10061 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 10062 } 10063 } 10064 PetscFunctionReturn(0); 10065 } 10066 10067 /* This will only work for interpolated meshes */ 10068 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 10069 { 10070 DM rdm; 10071 PetscInt *depthSize; 10072 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 10073 PetscErrorCode ierr; 10074 10075 PetscFunctionBegin; 10076 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 10077 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 10078 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 10079 ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr); 10080 /* Calculate number of new points of each depth */ 10081 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 10082 if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement"); 10083 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 10084 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 10085 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 10086 /* Step 1: Set chart */ 10087 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 10088 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 10089 /* Step 2: Set cone/support sizes (automatically stratifies) */ 10090 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10091 /* Step 3: Setup refined DM */ 10092 ierr = DMSetUp(rdm);CHKERRQ(ierr); 10093 /* Step 4: Set cones and supports (automatically symmetrizes) */ 10094 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10095 /* Step 5: Create pointSF */ 10096 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10097 /* Step 6: Create labels */ 10098 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10099 /* Step 7: Set coordinates */ 10100 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10101 ierr = PetscFree(depthSize);CHKERRQ(ierr); 10102 10103 *dmRefined = rdm; 10104 PetscFunctionReturn(0); 10105 } 10106 10107 /*@ 10108 DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 10109 10110 Input Parameter: 10111 . dm - The coarse DM 10112 10113 Output Parameter: 10114 . fpointIS - The IS of all the fine points which exist in the original coarse mesh 10115 10116 Level: developer 10117 10118 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS() 10119 @*/ 10120 PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 10121 { 10122 CellRefiner cellRefiner; 10123 PetscInt *depthSize, *fpoints; 10124 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 10125 PetscInt depth, pStart, pEnd, p, vStart, vEnd, v; 10126 PetscErrorCode ierr; 10127 10128 PetscFunctionBegin; 10129 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 10130 ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 10131 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 10132 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 10133 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 10134 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 10135 if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 10136 ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr); 10137 for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 10138 switch (cellRefiner) { 10139 case REFINER_SIMPLEX_1D: 10140 case REFINER_SIMPLEX_2D: 10141 case REFINER_HYBRID_SIMPLEX_2D: 10142 case REFINER_HEX_2D: 10143 case REFINER_HYBRID_HEX_2D: 10144 case REFINER_SIMPLEX_3D: 10145 case REFINER_HYBRID_SIMPLEX_3D: 10146 case REFINER_HEX_3D: 10147 case REFINER_HYBRID_HEX_3D: 10148 for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart); 10149 break; 10150 default: 10151 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %D", cellRefiner); 10152 } 10153 ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 10154 ierr = PetscFree(depthSize);CHKERRQ(ierr); 10155 PetscFunctionReturn(0); 10156 } 10157 10158 /*@ 10159 DMPlexSetRefinementUniform - Set the flag for uniform refinement 10160 10161 Input Parameters: 10162 + dm - The DM 10163 - refinementUniform - The flag for uniform refinement 10164 10165 Level: developer 10166 10167 .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10168 @*/ 10169 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 10170 { 10171 DM_Plex *mesh = (DM_Plex*) dm->data; 10172 10173 PetscFunctionBegin; 10174 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10175 mesh->refinementUniform = refinementUniform; 10176 PetscFunctionReturn(0); 10177 } 10178 10179 /*@ 10180 DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement 10181 10182 Input Parameter: 10183 . dm - The DM 10184 10185 Output Parameter: 10186 . refinementUniform - The flag for uniform refinement 10187 10188 Level: developer 10189 10190 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10191 @*/ 10192 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 10193 { 10194 DM_Plex *mesh = (DM_Plex*) dm->data; 10195 10196 PetscFunctionBegin; 10197 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10198 PetscValidPointer(refinementUniform, 2); 10199 *refinementUniform = mesh->refinementUniform; 10200 PetscFunctionReturn(0); 10201 } 10202 10203 /*@ 10204 DMPlexSetRefinementLimit - Set the maximum cell volume for refinement 10205 10206 Input Parameters: 10207 + dm - The DM 10208 - refinementLimit - The maximum cell volume in the refined mesh 10209 10210 Level: developer 10211 10212 .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 10213 @*/ 10214 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 10215 { 10216 DM_Plex *mesh = (DM_Plex*) dm->data; 10217 10218 PetscFunctionBegin; 10219 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10220 mesh->refinementLimit = refinementLimit; 10221 PetscFunctionReturn(0); 10222 } 10223 10224 /*@ 10225 DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement 10226 10227 Input Parameter: 10228 . dm - The DM 10229 10230 Output Parameter: 10231 . refinementLimit - The maximum cell volume in the refined mesh 10232 10233 Level: developer 10234 10235 .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 10236 @*/ 10237 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 10238 { 10239 DM_Plex *mesh = (DM_Plex*) dm->data; 10240 10241 PetscFunctionBegin; 10242 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10243 PetscValidPointer(refinementLimit, 2); 10244 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 10245 *refinementLimit = mesh->refinementLimit; 10246 PetscFunctionReturn(0); 10247 } 10248 10249 /*@ 10250 DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement 10251 10252 Input Parameters: 10253 + dm - The DM 10254 - refinementFunc - Function giving the maximum cell volume in the refined mesh 10255 10256 Note: The calling sequence is refinementFunc(coords, limit) 10257 $ coords - Coordinates of the current point, usually a cell centroid 10258 $ limit - The maximum cell volume for a cell containing this point 10259 10260 Level: developer 10261 10262 .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10263 @*/ 10264 PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *)) 10265 { 10266 DM_Plex *mesh = (DM_Plex*) dm->data; 10267 10268 PetscFunctionBegin; 10269 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10270 mesh->refinementFunc = refinementFunc; 10271 PetscFunctionReturn(0); 10272 } 10273 10274 /*@ 10275 DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement 10276 10277 Input Parameter: 10278 . dm - The DM 10279 10280 Output Parameter: 10281 . refinementFunc - Function giving the maximum cell volume in the refined mesh 10282 10283 Note: The calling sequence is refinementFunc(coords, limit) 10284 $ coords - Coordinates of the current point, usually a cell centroid 10285 $ limit - The maximum cell volume for a cell containing this point 10286 10287 Level: developer 10288 10289 .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10290 @*/ 10291 PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *)) 10292 { 10293 DM_Plex *mesh = (DM_Plex*) dm->data; 10294 10295 PetscFunctionBegin; 10296 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10297 PetscValidPointer(refinementFunc, 2); 10298 *refinementFunc = mesh->refinementFunc; 10299 PetscFunctionReturn(0); 10300 } 10301 10302 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 10303 { 10304 PetscInt dim, cStart, cEnd, coneSize, cMax, fMax; 10305 PetscErrorCode ierr; 10306 10307 PetscFunctionBegin; 10308 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 10309 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 10310 if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; PetscFunctionReturn(0);} 10311 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 10312 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, NULL, NULL);CHKERRQ(ierr); 10313 switch (dim) { 10314 case 1: 10315 switch (coneSize) { 10316 case 2: 10317 *cellRefiner = REFINER_SIMPLEX_1D; 10318 break; 10319 default: 10320 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim); 10321 } 10322 break; 10323 case 2: 10324 switch (coneSize) { 10325 case 3: 10326 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_2D; 10327 else *cellRefiner = REFINER_SIMPLEX_2D; 10328 break; 10329 case 4: 10330 if (cMax >= 0 && fMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_2D; 10331 else *cellRefiner = REFINER_HEX_2D; 10332 break; 10333 default: 10334 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim); 10335 } 10336 break; 10337 case 3: 10338 switch (coneSize) { 10339 case 4: 10340 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D; 10341 else *cellRefiner = REFINER_SIMPLEX_3D; 10342 break; 10343 case 5: 10344 if (cMax == 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D; 10345 else SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim); 10346 break; 10347 case 6: 10348 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_3D; 10349 else *cellRefiner = REFINER_HEX_3D; 10350 break; 10351 default: 10352 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim); 10353 } 10354 break; 10355 default: 10356 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %D for cell refiner", dim); 10357 } 10358 PetscFunctionReturn(0); 10359 } 10360 10361 PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined) 10362 { 10363 PetscBool isUniform; 10364 PetscErrorCode ierr; 10365 10366 PetscFunctionBegin; 10367 ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 10368 if (isUniform) { 10369 CellRefiner cellRefiner; 10370 PetscBool localized; 10371 10372 ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 10373 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 10374 ierr = DMPlexRefineUniform_Internal(dm, cellRefiner, dmRefined);CHKERRQ(ierr); 10375 ierr = DMPlexSetRegularRefinement(*dmRefined, PETSC_TRUE);CHKERRQ(ierr); 10376 ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr); 10377 if (localized) {ierr = DMLocalizeCoordinates(*dmRefined);CHKERRQ(ierr);} 10378 } else { 10379 ierr = DMPlexRefine_Internal(dm, NULL, dmRefined);CHKERRQ(ierr); 10380 } 10381 PetscFunctionReturn(0); 10382 } 10383 10384 PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[]) 10385 { 10386 DM cdm = dm; 10387 PetscInt r; 10388 PetscBool isUniform, localized; 10389 PetscErrorCode ierr; 10390 10391 PetscFunctionBegin; 10392 ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 10393 ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 10394 if (isUniform) { 10395 for (r = 0; r < nlevels; ++r) { 10396 CellRefiner cellRefiner; 10397 10398 ierr = DMPlexGetCellRefiner_Internal(cdm, &cellRefiner);CHKERRQ(ierr); 10399 ierr = DMPlexRefineUniform_Internal(cdm, cellRefiner, &dmRefined[r]);CHKERRQ(ierr); 10400 ierr = DMSetCoarsenLevel(dmRefined[r], cdm->leveldown);CHKERRQ(ierr); 10401 ierr = DMSetRefineLevel(dmRefined[r], cdm->levelup+1);CHKERRQ(ierr); 10402 ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 10403 if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 10404 ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 10405 ierr = DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);CHKERRQ(ierr); 10406 cdm = dmRefined[r]; 10407 } 10408 } else { 10409 for (r = 0; r < nlevels; ++r) { 10410 ierr = DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);CHKERRQ(ierr); 10411 ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 10412 if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 10413 ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 10414 cdm = dmRefined[r]; 10415 } 10416 } 10417 PetscFunctionReturn(0); 10418 } 10419