1 #include <petsc-private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2 #include <petscsf.h> 3 4 #undef __FUNCT__ 5 #define __FUNCT__ "GetDepthStart_Private" 6 PETSC_STATIC_INLINE PetscErrorCode GetDepthStart_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cStart, PetscInt *fStart, PetscInt *eStart, PetscInt *vStart) 7 { 8 PetscFunctionBegin; 9 if (cStart) *cStart = 0; 10 if (vStart) *vStart = depthSize[depth]; 11 if (fStart) *fStart = depthSize[depth] + depthSize[0]; 12 if (eStart) *eStart = depthSize[depth] + depthSize[0] + depthSize[depth-1]; 13 PetscFunctionReturn(0); 14 } 15 16 #undef __FUNCT__ 17 #define __FUNCT__ "GetDepthEnd_Private" 18 PETSC_STATIC_INLINE PetscErrorCode GetDepthEnd_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cEnd, PetscInt *fEnd, PetscInt *eEnd, PetscInt *vEnd) 19 { 20 PetscFunctionBegin; 21 if (cEnd) *cEnd = depthSize[depth]; 22 if (vEnd) *vEnd = depthSize[depth] + depthSize[0]; 23 if (fEnd) *fEnd = depthSize[depth] + depthSize[0] + depthSize[depth-1]; 24 if (eEnd) *eEnd = depthSize[depth] + depthSize[0] + depthSize[depth-1] + depthSize[1]; 25 PetscFunctionReturn(0); 26 } 27 28 #undef __FUNCT__ 29 #define __FUNCT__ "CellRefinerGetSizes" 30 PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[]) 31 { 32 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 33 PetscErrorCode ierr; 34 35 PetscFunctionBegin; 36 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 37 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 38 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 39 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 40 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 41 switch (refiner) { 42 case 0: 43 break; 44 case 1: 45 /* Simplicial 2D */ 46 depthSize[0] = vEnd - vStart + fEnd - fStart; /* Add a vertex on every face */ 47 depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */ 48 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 49 break; 50 case 3: 51 /* Hybrid Simplicial 2D */ 52 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 53 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 54 depthSize[0] = vEnd - vStart + fMax - fStart; /* Add a vertex on every face, but not hybrid faces */ 55 depthSize[1] = 2*(fMax - fStart) + 3*(cMax - cStart) + (fEnd - fMax) + (cEnd - cMax); /* Every interior face is split into 2 faces, 3 faces are added for each interior cell, and one in each hybrid cell */ 56 depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax); /* Interior cells split into 4 cells, Hybrid cells split into 2 cells */ 57 break; 58 case 2: 59 /* Hex 2D */ 60 depthSize[0] = vEnd - vStart + cEnd - cStart + fEnd - fStart; /* Add a vertex on every face and cell */ 61 depthSize[1] = 2*(fEnd - fStart) + 4*(cEnd - cStart); /* Every face is split into 2 faces and 4 faces are added for each cell */ 62 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 63 break; 64 case 5: 65 /* Simplicial 3D */ 66 depthSize[0] = vEnd - vStart + eEnd - eStart; /* Add a vertex on every edge */ 67 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 */ 68 depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart); /* Every face split into 4 faces and 8 faces are added for each cell */ 69 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 70 break; 71 case 7: 72 /* Hybrid Simplicial 3D */ 73 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 74 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 75 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 76 /* Tetrahedra */ 77 depthSize[0] = vEnd - vStart + eMax - eStart; /* Add a vertex on every interior edge */ 78 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 */ 79 depthSize[2] = 4*(fMax - fStart) + 8*(cMax - cStart); /* Every interior face split into 4 faces, 8 faces added for each interior cell */ 80 depthSize[3] = 8*(cMax - cStart); /* Every interior cell split into 8 cells */ 81 /* Triangular Prisms */ 82 depthSize[0] += 0; /* No hybrid vertices */ 83 depthSize[1] += (eEnd - eMax) + (fEnd - fMax); /* Every hybrid edge remains, 1 edge for every hybrid face */ 84 depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */ 85 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 86 break; 87 case 6: 88 /* Hex 3D */ 89 depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */ 90 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 */ 91 depthSize[2] = 4*(fEnd - fStart) + 12*(cEnd - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 92 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 93 break; 94 default: 95 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 96 } 97 PetscFunctionReturn(0); 98 } 99 100 /* Return triangle edge for orientation o, if it is r for o == 0 */ 101 PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) { 102 return (o < 0 ? 2-(o+r) : o+r)%3; 103 } 104 105 /* Return triangle subface for orientation o, if it is r for o == 0 */ 106 PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) { 107 return (o < 0 ? 3-(o+r) : o+r)%3; 108 } 109 110 /* Return quad edge for orientation o, if it is r for o == 0 */ 111 PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) { 112 return (o < 0 ? 3-(o+r) : o+r)%4; 113 } 114 115 /* Return quad subface for orientation o, if it is r for o == 0 */ 116 PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) { 117 return (o < 0 ? 4-(o+r) : o+r)%4; 118 } 119 120 #undef __FUNCT__ 121 #define __FUNCT__ "CellRefinerSetConeSizes" 122 PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 123 { 124 PetscInt depth, cStart, cStartNew, cEnd, cMax, c, vStart, vStartNew, vEnd, vMax, v, fStart, fStartNew, fEnd, fMax, f, eStart, eStartNew, eEnd, eMax, e, r; 125 PetscErrorCode ierr; 126 127 PetscFunctionBegin; 128 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 129 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 130 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 131 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 132 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 133 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 134 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 135 switch (refiner) { 136 case 0: break; 137 case 1: 138 /* Simplicial 2D */ 139 /* All cells have 3 faces */ 140 for (c = cStart; c < cEnd; ++c) { 141 for (r = 0; r < 4; ++r) { 142 const PetscInt newp = (c - cStart)*4 + r; 143 144 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 145 } 146 } 147 /* Split faces have 2 vertices and the same cells as the parent */ 148 for (f = fStart; f < fEnd; ++f) { 149 for (r = 0; r < 2; ++r) { 150 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 151 PetscInt size; 152 153 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 154 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 155 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 156 } 157 } 158 /* Interior faces have 2 vertices and 2 cells */ 159 for (c = cStart; c < cEnd; ++c) { 160 for (r = 0; r < 3; ++r) { 161 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 162 163 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 164 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 165 } 166 } 167 /* Old vertices have identical supports */ 168 for (v = vStart; v < vEnd; ++v) { 169 const PetscInt newp = vStartNew + (v - vStart); 170 PetscInt size; 171 172 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 173 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 174 } 175 /* Face vertices have 2 + cells*2 supports */ 176 for (f = fStart; f < fEnd; ++f) { 177 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 178 PetscInt size; 179 180 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 181 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr); 182 } 183 break; 184 case 2: 185 /* Hex 2D */ 186 /* All cells have 4 faces */ 187 for (c = cStart; c < cEnd; ++c) { 188 for (r = 0; r < 4; ++r) { 189 const PetscInt newp = (c - cStart)*4 + r; 190 191 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 192 } 193 } 194 /* Split faces have 2 vertices and the same cells as the parent */ 195 for (f = fStart; f < fEnd; ++f) { 196 for (r = 0; r < 2; ++r) { 197 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 198 PetscInt size; 199 200 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 201 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 202 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 203 } 204 } 205 /* Interior faces have 2 vertices and 2 cells */ 206 for (c = cStart; c < cEnd; ++c) { 207 for (r = 0; r < 4; ++r) { 208 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 209 210 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 211 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 212 } 213 } 214 /* Old vertices have identical supports */ 215 for (v = vStart; v < vEnd; ++v) { 216 const PetscInt newp = vStartNew + (v - vStart); 217 PetscInt size; 218 219 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 220 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 221 } 222 /* Face vertices have 2 + cells supports */ 223 for (f = fStart; f < fEnd; ++f) { 224 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 225 PetscInt size; 226 227 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 228 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 229 } 230 /* Cell vertices have 4 supports */ 231 for (c = cStart; c < cEnd; ++c) { 232 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 233 234 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 235 } 236 break; 237 case 3: 238 /* Hybrid Simplicial 2D */ 239 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 240 cMax = PetscMin(cEnd, cMax); 241 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 242 fMax = PetscMin(fEnd, fMax); 243 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 244 /* Interior cells have 3 faces */ 245 for (c = cStart; c < cMax; ++c) { 246 for (r = 0; r < 4; ++r) { 247 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 248 249 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 250 } 251 } 252 /* Hybrid cells have 4 faces */ 253 for (c = cMax; c < cEnd; ++c) { 254 for (r = 0; r < 2; ++r) { 255 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 256 257 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 258 } 259 } 260 /* Interior split faces have 2 vertices and the same cells as the parent */ 261 for (f = fStart; f < fMax; ++f) { 262 for (r = 0; r < 2; ++r) { 263 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 264 PetscInt size; 265 266 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 267 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 268 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 269 } 270 } 271 /* Interior cell faces have 2 vertices and 2 cells */ 272 for (c = cStart; c < cMax; ++c) { 273 for (r = 0; r < 3; ++r) { 274 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 275 276 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 277 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 278 } 279 } 280 /* Hybrid faces have 2 vertices and the same cells */ 281 for (f = fMax; f < fEnd; ++f) { 282 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 283 PetscInt size; 284 285 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 286 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 287 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 288 } 289 /* Hybrid cell faces have 2 vertices and 2 cells */ 290 for (c = cMax; c < cEnd; ++c) { 291 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 292 293 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 294 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 295 } 296 /* Old vertices have identical supports */ 297 for (v = vStart; v < vEnd; ++v) { 298 const PetscInt newp = vStartNew + (v - vStart); 299 PetscInt size; 300 301 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 302 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 303 } 304 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 305 for (f = fStart; f < fMax; ++f) { 306 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 307 const PetscInt *support; 308 PetscInt size, newSize = 2, s; 309 310 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 311 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 312 for (s = 0; s < size; ++s) { 313 if (support[s] >= cMax) newSize += 1; 314 else newSize += 2; 315 } 316 ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr); 317 } 318 break; 319 case 5: 320 /* Simplicial 3D */ 321 /* All cells have 4 faces */ 322 for (c = cStart; c < cEnd; ++c) { 323 for (r = 0; r < 8; ++r) { 324 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 325 326 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 327 } 328 } 329 /* Split faces have 3 edges and the same cells as the parent */ 330 for (f = fStart; f < fEnd; ++f) { 331 for (r = 0; r < 4; ++r) { 332 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 333 PetscInt size; 334 335 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 336 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 337 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 338 } 339 } 340 /* Interior faces have 3 edges and 2 cells */ 341 for (c = cStart; c < cEnd; ++c) { 342 for (r = 0; r < 8; ++r) { 343 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r; 344 345 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 346 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 347 } 348 } 349 /* Split edges have 2 vertices and the same faces */ 350 for (e = eStart; e < eEnd; ++e) { 351 for (r = 0; r < 2; ++r) { 352 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 353 PetscInt size; 354 355 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 356 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 357 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 358 } 359 } 360 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 361 for (f = fStart; f < fEnd; ++f) { 362 for (r = 0; r < 3; ++r) { 363 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 364 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 365 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 366 367 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 368 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 369 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 370 for (s = 0; s < supportSize; ++s) { 371 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 372 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 373 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 374 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 375 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 376 er = ornt[c] < 0 ? (-(ornt[c]+1) + 2-r)%3 : (ornt[c] + r)%3; 377 if (er == eint[c]) { 378 intFaces += 1; 379 } else { 380 intFaces += 2; 381 } 382 } 383 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 384 } 385 } 386 /* Interior edges have 2 vertices and 4 faces */ 387 for (c = cStart; c < cEnd; ++c) { 388 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 389 390 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 391 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 392 } 393 /* Old vertices have identical supports */ 394 for (v = vStart; v < vEnd; ++v) { 395 const PetscInt newp = vStartNew + (v - vStart); 396 PetscInt size; 397 398 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 399 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 400 } 401 /* Edge vertices have 2 + faces*2 + cells*0/1 supports */ 402 for (e = eStart; e < eEnd; ++e) { 403 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 404 PetscInt size, *star = NULL, starSize, s, cellSize = 0; 405 406 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 407 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 408 for (s = 0; s < starSize*2; s += 2) { 409 const PetscInt *cone, *ornt; 410 PetscInt e01, e23; 411 412 if ((star[s] >= cStart) && (star[s] < cEnd)) { 413 /* Check edge 0-1 */ 414 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 415 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 416 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 417 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 418 /* Check edge 2-3 */ 419 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 420 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 421 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 422 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 423 if ((e01 == e) || (e23 == e)) ++cellSize; 424 } 425 } 426 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 427 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr); 428 } 429 break; 430 case 7: 431 /* Hybrid Simplicial 3D */ 432 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart), 433 eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 434 /* Interior cells have 4 faces */ 435 for (c = cStart; c < cMax; ++c) { 436 for (r = 0; r < 8; ++r) { 437 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 438 439 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 440 } 441 } 442 /* Hybrid cells have 5 faces */ 443 for (c = cMax; c < cEnd; ++c) { 444 for (r = 0; r < 4; ++r) { 445 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 446 447 ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr); 448 } 449 } 450 /* Interior split faces have 3 edges and the same cells as the parent */ 451 for (f = fStart; f < fMax; ++f) { 452 for (r = 0; r < 4; ++r) { 453 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 454 PetscInt size; 455 456 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 457 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 458 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 459 } 460 } 461 /* Interior cell faces have 3 edges and 2 cells */ 462 for (c = cStart; c < cMax; ++c) { 463 for (r = 0; r < 8; ++r) { 464 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r; 465 466 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 467 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 468 } 469 } 470 /* Hybrid split faces have 4 edges and the same cells as the parent */ 471 for (f = fMax; f < fEnd; ++f) { 472 for (r = 0; r < 2; ++r) { 473 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 474 PetscInt size; 475 476 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 477 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 478 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 479 } 480 } 481 /* Hybrid cells faces have 4 edges and 2 cells */ 482 for (c = cMax; c < cEnd; ++c) { 483 for (r = 0; r < 3; ++r) { 484 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 485 486 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 487 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 488 } 489 } 490 /* Interior split edges have 2 vertices and the same faces */ 491 for (e = eStart; e < eMax; ++e) { 492 for (r = 0; r < 2; ++r) { 493 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 494 PetscInt size; 495 496 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 497 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 498 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 499 } 500 } 501 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 502 for (f = fStart; f < fMax; ++f) { 503 for (r = 0; r < 3; ++r) { 504 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 505 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 506 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 507 508 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 509 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 510 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 511 for (s = 0; s < supportSize; ++s) { 512 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 513 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 514 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 515 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 516 if (support[s] < cMax) { 517 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 518 er = ornt[c] < 0 ? (-(ornt[c]+1) + 2-r)%3 : (ornt[c] + r)%3; 519 if (er == eint[c]) { 520 intFaces += 1; 521 } else { 522 intFaces += 2; 523 } 524 } else { 525 intFaces += 1; 526 } 527 } 528 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 529 } 530 } 531 /* Interior cell edges have 2 vertices and 4 faces */ 532 for (c = cStart; c < cMax; ++c) { 533 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 534 535 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 536 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 537 } 538 /* Hybrid edges have 2 vertices and the same faces */ 539 for (e = eMax; e < eEnd; ++e) { 540 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 541 PetscInt size; 542 543 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 544 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 545 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 546 } 547 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 548 for (f = fMax; f < fEnd; ++f) { 549 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 550 PetscInt size; 551 552 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 553 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 554 ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr); 555 } 556 /* Interior vertices have identical supports */ 557 for (v = vStart; v < vEnd; ++v) { 558 const PetscInt newp = vStartNew + (v - vStart); 559 PetscInt size; 560 561 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 562 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 563 } 564 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 565 for (e = eStart; e < eMax; ++e) { 566 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 567 const PetscInt *support; 568 PetscInt size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0; 569 570 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 571 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 572 for (s = 0; s < size; ++s) { 573 if (support[s] < fMax) faceSize += 2; 574 else faceSize += 1; 575 } 576 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 577 for (s = 0; s < starSize*2; s += 2) { 578 const PetscInt *cone, *ornt; 579 PetscInt e01, e23; 580 581 if ((star[s] >= cStart) && (star[s] < cMax)) { 582 /* Check edge 0-1 */ 583 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 584 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 585 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 586 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 587 /* Check edge 2-3 */ 588 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 589 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 590 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 591 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 592 if ((e01 == e) || (e23 == e)) ++cellSize; 593 } 594 } 595 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 596 ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr); 597 } 598 break; 599 case 6: 600 /* Hex 3D */ 601 /* All cells have 6 faces */ 602 for (c = cStart; c < cEnd; ++c) { 603 for (r = 0; r < 8; ++r) { 604 const PetscInt newp = (c - cStart)*8 + r; 605 606 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 607 } 608 } 609 /* Split faces have 4 edges and the same cells as the parent */ 610 for (f = fStart; f < fEnd; ++f) { 611 for (r = 0; r < 4; ++r) { 612 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 613 PetscInt size; 614 615 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 616 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 617 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 618 } 619 } 620 /* Interior faces have 4 edges and 2 cells */ 621 for (c = cStart; c < cEnd; ++c) { 622 for (r = 0; r < 12; ++r) { 623 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 624 625 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 626 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 627 } 628 } 629 /* Split edges have 2 vertices and the same faces as the parent */ 630 for (e = eStart; e < eEnd; ++e) { 631 for (r = 0; r < 2; ++r) { 632 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 633 PetscInt size; 634 635 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 636 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 637 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 638 } 639 } 640 /* Face edges have 2 vertices and 2+cells faces */ 641 for (f = fStart; f < fEnd; ++f) { 642 for (r = 0; r < 4; ++r) { 643 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 644 PetscInt size; 645 646 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 647 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 648 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 649 } 650 } 651 /* Cell edges have 2 vertices and 4 faces */ 652 for (c = cStart; c < cEnd; ++c) { 653 for (r = 0; r < 6; ++r) { 654 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 655 656 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 657 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 658 } 659 } 660 /* Old vertices have identical supports */ 661 for (v = vStart; v < vEnd; ++v) { 662 const PetscInt newp = vStartNew + (v - vStart); 663 PetscInt size; 664 665 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 666 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 667 } 668 /* Edge vertices have 2 + faces supports */ 669 for (e = eStart; e < eEnd; ++e) { 670 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 671 PetscInt size; 672 673 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 674 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 675 } 676 /* Face vertices have 4 + cells supports */ 677 for (f = fStart; f < fEnd; ++f) { 678 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 679 PetscInt size; 680 681 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 682 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 683 } 684 /* Cell vertices have 6 supports */ 685 for (c = cStart; c < cEnd; ++c) { 686 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 687 688 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 689 } 690 break; 691 default: 692 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 693 } 694 PetscFunctionReturn(0); 695 } 696 697 #undef __FUNCT__ 698 #define __FUNCT__ "CellRefinerSetCones" 699 PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 700 { 701 const PetscInt *faces, cellInd[4] = {0, 1, 2, 3}; 702 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 703 PetscInt cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew, fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew; 704 PetscInt depth, maxSupportSize, *supportRef, c, f, e, v, r, p; 705 PetscErrorCode ierr; 706 707 PetscFunctionBegin; 708 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 709 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 710 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 711 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 712 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 713 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 714 if (refiner) { 715 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 716 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 717 } 718 switch (refiner) { 719 case 0: break; 720 case 1: 721 /* Simplicial 2D */ 722 /* 723 2 724 |\ 725 | \ 726 | \ 727 | \ 728 | C \ 729 | \ 730 | \ 731 2---1---1 732 |\ D / \ 733 | 2 0 \ 734 |A \ / B \ 735 0---0-------1 736 */ 737 /* All cells have 3 faces */ 738 for (c = cStart; c < cEnd; ++c) { 739 const PetscInt newp = cStartNew + (c - cStart)*4; 740 const PetscInt *cone, *ornt; 741 PetscInt coneNew[3], orntNew[3]; 742 743 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 744 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 745 /* A triangle */ 746 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 747 orntNew[0] = ornt[0]; 748 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 749 orntNew[1] = -2; 750 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 751 orntNew[2] = ornt[2]; 752 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 753 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 754 #if 1 755 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew); 756 for (p = 0; p < 3; ++p) { 757 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 758 } 759 #endif 760 /* B triangle */ 761 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 762 orntNew[0] = ornt[0]; 763 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 764 orntNew[1] = ornt[1]; 765 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 766 orntNew[2] = -2; 767 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 768 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 769 #if 1 770 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew); 771 for (p = 0; p < 3; ++p) { 772 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 773 } 774 #endif 775 /* C triangle */ 776 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 777 orntNew[0] = -2; 778 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 779 orntNew[1] = ornt[1]; 780 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 781 orntNew[2] = ornt[2]; 782 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 783 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 784 #if 1 785 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew); 786 for (p = 0; p < 3; ++p) { 787 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 788 } 789 #endif 790 /* D triangle */ 791 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 792 orntNew[0] = 0; 793 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 794 orntNew[1] = 0; 795 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 796 orntNew[2] = 0; 797 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 798 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 799 #if 1 800 if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew); 801 for (p = 0; p < 3; ++p) { 802 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 803 } 804 #endif 805 } 806 /* Split faces have 2 vertices and the same cells as the parent */ 807 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 808 ierr = PetscMalloc((2 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr); 809 for (f = fStart; f < fEnd; ++f) { 810 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 811 812 for (r = 0; r < 2; ++r) { 813 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 814 const PetscInt *cone, *ornt, *support; 815 PetscInt coneNew[2], coneSize, c, supportSize, s; 816 817 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 818 coneNew[0] = vStartNew + (cone[0] - vStart); 819 coneNew[1] = vStartNew + (cone[1] - vStart); 820 coneNew[(r+1)%2] = newv; 821 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 822 #if 1 823 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 824 for (p = 0; p < 2; ++p) { 825 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 826 } 827 #endif 828 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 829 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 830 for (s = 0; s < supportSize; ++s) { 831 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 832 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 833 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 834 for (c = 0; c < coneSize; ++c) { 835 if (cone[c] == f) break; 836 } 837 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 838 } 839 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 840 #if 1 841 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 842 for (p = 0; p < supportSize; ++p) { 843 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew); 844 } 845 #endif 846 } 847 } 848 /* Interior faces have 2 vertices and 2 cells */ 849 for (c = cStart; c < cEnd; ++c) { 850 const PetscInt *cone; 851 852 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 853 for (r = 0; r < 3; ++r) { 854 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 855 PetscInt coneNew[2]; 856 PetscInt supportNew[2]; 857 858 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 859 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 860 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 861 #if 1 862 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 863 for (p = 0; p < 2; ++p) { 864 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 865 } 866 #endif 867 supportNew[0] = (c - cStart)*4 + (r+1)%3; 868 supportNew[1] = (c - cStart)*4 + 3; 869 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 870 #if 1 871 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 872 for (p = 0; p < 2; ++p) { 873 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 874 } 875 #endif 876 } 877 } 878 /* Old vertices have identical supports */ 879 for (v = vStart; v < vEnd; ++v) { 880 const PetscInt newp = vStartNew + (v - vStart); 881 const PetscInt *support, *cone; 882 PetscInt size, s; 883 884 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 885 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 886 for (s = 0; s < size; ++s) { 887 PetscInt r = 0; 888 889 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 890 if (cone[1] == v) r = 1; 891 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 892 } 893 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 894 #if 1 895 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 896 for (p = 0; p < size; ++p) { 897 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 898 } 899 #endif 900 } 901 /* Face vertices have 2 + cells*2 supports */ 902 for (f = fStart; f < fEnd; ++f) { 903 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 904 const PetscInt *cone, *support; 905 PetscInt size, s; 906 907 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 908 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 909 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 910 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 911 for (s = 0; s < size; ++s) { 912 PetscInt r = 0; 913 914 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 915 if (cone[1] == f) r = 1; 916 else if (cone[2] == f) r = 2; 917 supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 918 supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 919 } 920 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 921 #if 1 922 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 923 for (p = 0; p < 2+size*2; ++p) { 924 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 925 } 926 #endif 927 } 928 ierr = PetscFree(supportRef);CHKERRQ(ierr); 929 break; 930 case 2: 931 /* Hex 2D */ 932 /* 933 3---------2---------2 934 | | | 935 | D 2 C | 936 | | | 937 3----3----0----1----1 938 | | | 939 | A 0 B | 940 | | | 941 0---------0---------1 942 */ 943 /* All cells have 4 faces */ 944 for (c = cStart; c < cEnd; ++c) { 945 const PetscInt newp = (c - cStart)*4; 946 const PetscInt *cone, *ornt; 947 PetscInt coneNew[4], orntNew[4]; 948 949 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 950 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 951 /* A quad */ 952 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 953 orntNew[0] = ornt[0]; 954 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 955 orntNew[1] = 0; 956 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 957 orntNew[2] = -2; 958 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 959 orntNew[3] = ornt[3]; 960 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 961 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 962 #if 1 963 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew); 964 for (p = 0; p < 4; ++p) { 965 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 966 } 967 #endif 968 /* B quad */ 969 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 970 orntNew[0] = ornt[0]; 971 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 972 orntNew[1] = ornt[1]; 973 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 974 orntNew[2] = 0; 975 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 976 orntNew[3] = -2; 977 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 978 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 979 #if 1 980 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew); 981 for (p = 0; p < 4; ++p) { 982 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 983 } 984 #endif 985 /* C quad */ 986 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 987 orntNew[0] = -2; 988 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 989 orntNew[1] = ornt[1]; 990 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 991 orntNew[2] = ornt[2]; 992 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 993 orntNew[3] = 0; 994 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 995 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 996 #if 1 997 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew); 998 for (p = 0; p < 4; ++p) { 999 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1000 } 1001 #endif 1002 /* D quad */ 1003 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1004 orntNew[0] = 0; 1005 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1006 orntNew[1] = -2; 1007 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1008 orntNew[2] = ornt[2]; 1009 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 1010 orntNew[3] = ornt[3]; 1011 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1012 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1013 #if 1 1014 if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew); 1015 for (p = 0; p < 4; ++p) { 1016 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1017 } 1018 #endif 1019 } 1020 /* Split faces have 2 vertices and the same cells as the parent */ 1021 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1022 ierr = PetscMalloc((2 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr); 1023 for (f = fStart; f < fEnd; ++f) { 1024 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1025 1026 for (r = 0; r < 2; ++r) { 1027 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1028 const PetscInt *cone, *ornt, *support; 1029 PetscInt coneNew[2], coneSize, c, supportSize, s; 1030 1031 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1032 coneNew[0] = vStartNew + (cone[0] - vStart); 1033 coneNew[1] = vStartNew + (cone[1] - vStart); 1034 coneNew[(r+1)%2] = newv; 1035 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1036 #if 1 1037 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1038 for (p = 0; p < 2; ++p) { 1039 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 1040 } 1041 #endif 1042 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1043 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1044 for (s = 0; s < supportSize; ++s) { 1045 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1046 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1047 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1048 for (c = 0; c < coneSize; ++c) { 1049 if (cone[c] == f) break; 1050 } 1051 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 1052 } 1053 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1054 #if 1 1055 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1056 for (p = 0; p < supportSize; ++p) { 1057 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew); 1058 } 1059 #endif 1060 } 1061 } 1062 /* Interior faces have 2 vertices and 2 cells */ 1063 for (c = cStart; c < cEnd; ++c) { 1064 const PetscInt *cone; 1065 PetscInt coneNew[2], supportNew[2]; 1066 1067 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1068 for (r = 0; r < 4; ++r) { 1069 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 1070 1071 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1072 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1073 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1074 #if 1 1075 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1076 for (p = 0; p < 2; ++p) { 1077 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 1078 } 1079 #endif 1080 supportNew[0] = (c - cStart)*4 + r; 1081 supportNew[1] = (c - cStart)*4 + (r+1)%4; 1082 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1083 #if 1 1084 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1085 for (p = 0; p < 2; ++p) { 1086 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 1087 } 1088 #endif 1089 } 1090 } 1091 /* Old vertices have identical supports */ 1092 for (v = vStart; v < vEnd; ++v) { 1093 const PetscInt newp = vStartNew + (v - vStart); 1094 const PetscInt *support, *cone; 1095 PetscInt size, s; 1096 1097 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1098 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1099 for (s = 0; s < size; ++s) { 1100 PetscInt r = 0; 1101 1102 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1103 if (cone[1] == v) r = 1; 1104 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1105 } 1106 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1107 #if 1 1108 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1109 for (p = 0; p < size; ++p) { 1110 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 1111 } 1112 #endif 1113 } 1114 /* Face vertices have 2 + cells supports */ 1115 for (f = fStart; f < fEnd; ++f) { 1116 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1117 const PetscInt *cone, *support; 1118 PetscInt size, s; 1119 1120 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1121 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1122 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1123 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1124 for (s = 0; s < size; ++s) { 1125 PetscInt r = 0; 1126 1127 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1128 if (cone[1] == f) r = 1; 1129 else if (cone[2] == f) r = 2; 1130 else if (cone[3] == f) r = 3; 1131 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r; 1132 } 1133 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1134 #if 1 1135 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1136 for (p = 0; p < 2+size; ++p) { 1137 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 1138 } 1139 #endif 1140 } 1141 /* Cell vertices have 4 supports */ 1142 for (c = cStart; c < cEnd; ++c) { 1143 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1144 PetscInt supportNew[4]; 1145 1146 for (r = 0; r < 4; ++r) { 1147 supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 1148 } 1149 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1150 } 1151 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1152 break; 1153 case 3: 1154 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1155 cMax = PetscMin(cEnd, cMax); 1156 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1157 fMax = PetscMin(fEnd, fMax); 1158 /* Interior cells have 3 faces */ 1159 for (c = cStart; c < cMax; ++c) { 1160 const PetscInt newp = cStartNew + (c - cStart)*4; 1161 const PetscInt *cone, *ornt; 1162 PetscInt coneNew[3], orntNew[3]; 1163 1164 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1165 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1166 /* A triangle */ 1167 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1168 orntNew[0] = ornt[0]; 1169 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 1170 orntNew[1] = -2; 1171 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1172 orntNew[2] = ornt[2]; 1173 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1174 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1175 #if 1 1176 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew); 1177 for (p = 0; p < 3; ++p) { 1178 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1179 } 1180 #endif 1181 /* B triangle */ 1182 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1183 orntNew[0] = ornt[0]; 1184 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1185 orntNew[1] = ornt[1]; 1186 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 1187 orntNew[2] = -2; 1188 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1189 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1190 #if 1 1191 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew); 1192 for (p = 0; p < 3; ++p) { 1193 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1194 } 1195 #endif 1196 /* C triangle */ 1197 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 1198 orntNew[0] = -2; 1199 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1200 orntNew[1] = ornt[1]; 1201 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1202 orntNew[2] = ornt[2]; 1203 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1204 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1205 #if 1 1206 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew); 1207 for (p = 0; p < 3; ++p) { 1208 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1209 } 1210 #endif 1211 /* D triangle */ 1212 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 1213 orntNew[0] = 0; 1214 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 1215 orntNew[1] = 0; 1216 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 1217 orntNew[2] = 0; 1218 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1219 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1220 #if 1 1221 if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew); 1222 for (p = 0; p < 3; ++p) { 1223 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1224 } 1225 #endif 1226 } 1227 /* 1228 2----3----3 1229 | | 1230 | B | 1231 | | 1232 0----4--- 1 1233 | | 1234 | A | 1235 | | 1236 0----2----1 1237 */ 1238 /* Hybrid cells have 4 faces */ 1239 for (c = cMax; c < cEnd; ++c) { 1240 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 1241 const PetscInt *cone, *ornt; 1242 PetscInt coneNew[4], orntNew[4]; 1243 1244 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1245 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1246 /* A quad */ 1247 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1248 orntNew[0] = ornt[0]; 1249 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1250 orntNew[1] = ornt[1]; 1251 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2] - fMax); 1252 orntNew[2] = 0; 1253 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1254 orntNew[3] = 0; 1255 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1256 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1257 #if 1 1258 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew); 1259 for (p = 0; p < 4; ++p) { 1260 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1261 } 1262 #endif 1263 /* B quad */ 1264 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1265 orntNew[0] = ornt[0]; 1266 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1267 orntNew[1] = ornt[1]; 1268 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1269 orntNew[2] = 0; 1270 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3] - fMax); 1271 orntNew[3] = 0; 1272 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1273 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1274 #if 1 1275 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew); 1276 for (p = 0; p < 4; ++p) { 1277 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1278 } 1279 #endif 1280 } 1281 /* Interior split faces have 2 vertices and the same cells as the parent */ 1282 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1283 ierr = PetscMalloc((2 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr); 1284 for (f = fStart; f < fMax; ++f) { 1285 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1286 1287 for (r = 0; r < 2; ++r) { 1288 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1289 const PetscInt *cone, *ornt, *support; 1290 PetscInt coneNew[2], coneSize, c, supportSize, s; 1291 1292 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1293 coneNew[0] = vStartNew + (cone[0] - vStart); 1294 coneNew[1] = vStartNew + (cone[1] - vStart); 1295 coneNew[(r+1)%2] = newv; 1296 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1297 #if 1 1298 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1299 for (p = 0; p < 2; ++p) { 1300 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 1301 } 1302 #endif 1303 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1304 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1305 for (s = 0; s < supportSize; ++s) { 1306 if (support[s] >= cMax) { 1307 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 1308 } else { 1309 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1310 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1311 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1312 for (c = 0; c < coneSize; ++c) { 1313 if (cone[c] == f) break; 1314 } 1315 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1316 } 1317 } 1318 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1319 #if 1 1320 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1321 for (p = 0; p < supportSize; ++p) { 1322 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew); 1323 } 1324 #endif 1325 } 1326 } 1327 /* Interior cell faces have 2 vertices and 2 cells */ 1328 for (c = cStart; c < cMax; ++c) { 1329 const PetscInt *cone; 1330 1331 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1332 for (r = 0; r < 3; ++r) { 1333 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 1334 PetscInt coneNew[2]; 1335 PetscInt supportNew[2]; 1336 1337 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1338 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1339 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1340 #if 1 1341 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1342 for (p = 0; p < 2; ++p) { 1343 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 1344 } 1345 #endif 1346 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1347 supportNew[1] = (c - cStart)*4 + 3; 1348 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1349 #if 1 1350 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1351 for (p = 0; p < 2; ++p) { 1352 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 1353 } 1354 #endif 1355 } 1356 } 1357 /* Interior hybrid faces have 2 vertices and the same cells */ 1358 for (f = fMax; f < fEnd; ++f) { 1359 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 1360 const PetscInt *cone; 1361 const PetscInt *support; 1362 PetscInt coneNew[2]; 1363 PetscInt supportNew[2]; 1364 PetscInt size, s, r; 1365 1366 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1367 coneNew[0] = vStartNew + (cone[0] - vStart); 1368 coneNew[1] = vStartNew + (cone[1] - vStart); 1369 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1370 #if 1 1371 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1372 for (p = 0; p < 2; ++p) { 1373 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 1374 } 1375 #endif 1376 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1377 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1378 for (s = 0; s < size; ++s) { 1379 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1380 for (r = 0; r < 2; ++r) { 1381 if (cone[r+2] == f) break; 1382 } 1383 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 1384 } 1385 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1386 #if 1 1387 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1388 for (p = 0; p < size; ++p) { 1389 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 1390 } 1391 #endif 1392 } 1393 /* Cell hybrid faces have 2 vertices and 2 cells */ 1394 for (c = cMax; c < cEnd; ++c) { 1395 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1396 const PetscInt *cone; 1397 PetscInt coneNew[2]; 1398 PetscInt supportNew[2]; 1399 1400 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1401 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 1402 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 1403 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1404 #if 1 1405 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1406 for (p = 0; p < 2; ++p) { 1407 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 1408 } 1409 #endif 1410 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 1411 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 1412 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1413 #if 1 1414 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1415 for (p = 0; p < 2; ++p) { 1416 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 1417 } 1418 #endif 1419 } 1420 /* Old vertices have identical supports */ 1421 for (v = vStart; v < vEnd; ++v) { 1422 const PetscInt newp = vStartNew + (v - vStart); 1423 const PetscInt *support, *cone; 1424 PetscInt size, s; 1425 1426 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1427 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1428 for (s = 0; s < size; ++s) { 1429 if (support[s] >= fMax) { 1430 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax); 1431 } else { 1432 PetscInt r = 0; 1433 1434 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1435 if (cone[1] == v) r = 1; 1436 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1437 } 1438 } 1439 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1440 #if 1 1441 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1442 for (p = 0; p < size; ++p) { 1443 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 1444 } 1445 #endif 1446 } 1447 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 1448 for (f = fStart; f < fMax; ++f) { 1449 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1450 const PetscInt *cone, *support; 1451 PetscInt size, newSize = 2, s; 1452 1453 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1454 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1455 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1456 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1457 for (s = 0; s < size; ++s) { 1458 PetscInt r = 0; 1459 1460 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1461 if (support[s] >= cMax) { 1462 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax); 1463 1464 newSize += 1; 1465 } else { 1466 if (cone[1] == f) r = 1; 1467 else if (cone[2] == f) r = 2; 1468 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1469 supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r; 1470 1471 newSize += 2; 1472 } 1473 } 1474 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1475 #if 1 1476 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1477 for (p = 0; p < newSize; ++p) { 1478 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 1479 } 1480 #endif 1481 } 1482 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1483 break; 1484 case 5: 1485 /* Simplicial 3D */ 1486 /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 1487 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 1488 for (c = cStart; c < cEnd; ++c) { 1489 const PetscInt newp = cStartNew + (c - cStart)*8; 1490 const PetscInt *cone, *ornt; 1491 PetscInt coneNew[4], orntNew[4]; 1492 1493 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1494 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1495 /* A tetrahedron: {0, a, c, d} */ 1496 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 1497 orntNew[0] = ornt[0]; 1498 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 1499 orntNew[1] = ornt[1]; 1500 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 1501 orntNew[2] = ornt[2]; 1502 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 1503 orntNew[3] = 0; 1504 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1505 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1506 #if 1 1507 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew); 1508 for (p = 0; p < 4; ++p) { 1509 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1510 } 1511 #endif 1512 /* B tetrahedron: {a, 1, b, e} */ 1513 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 1514 orntNew[0] = ornt[0]; 1515 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 1516 orntNew[1] = ornt[1]; 1517 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 1518 orntNew[2] = 0; 1519 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 1520 orntNew[3] = ornt[3]; 1521 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1522 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1523 #if 1 1524 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew); 1525 for (p = 0; p < 4; ++p) { 1526 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1527 } 1528 #endif 1529 /* C tetrahedron: {c, b, 2, f} */ 1530 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 1531 orntNew[0] = ornt[0]; 1532 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 1533 orntNew[1] = 0; 1534 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 1535 orntNew[2] = ornt[2]; 1536 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 1537 orntNew[3] = ornt[3]; 1538 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1539 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1540 #if 1 1541 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew); 1542 for (p = 0; p < 4; ++p) { 1543 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1544 } 1545 #endif 1546 /* D tetrahedron: {d, e, f, 3} */ 1547 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 1548 orntNew[0] = 0; 1549 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 1550 orntNew[1] = ornt[1]; 1551 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 1552 orntNew[2] = ornt[2]; 1553 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 1554 orntNew[3] = ornt[3]; 1555 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1556 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1557 #if 1 1558 if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew); 1559 for (p = 0; p < 4; ++p) { 1560 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1561 } 1562 #endif 1563 /* A' tetrahedron: {d, a, c, f} */ 1564 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 1565 orntNew[0] = -3; 1566 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 1567 orntNew[1] = 0; 1568 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + 3; 1569 orntNew[2] = ornt[2] < 0 ? -((-(ornt[2]+1)+2)%3+1) : (ornt[2]+2)%3; 1570 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 1571 orntNew[3] = 0; 1572 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 1573 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 1574 #if 1 1575 if ((newp+4 < cStartNew) || (newp+4 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+4, cStartNew, cEndNew); 1576 for (p = 0; p < 4; ++p) { 1577 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1578 } 1579 #endif 1580 /* B' tetrahedron: {e, b, a, f} */ 1581 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 1582 orntNew[0] = -3; 1583 coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3; 1584 orntNew[1] = ornt[3] < 0 ? -((-(ornt[3]+1)+1)%3+1) : (ornt[3]+1)%3; 1585 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 1586 orntNew[2] = 0; 1587 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 1588 orntNew[3] = 0; 1589 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 1590 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 1591 #if 1 1592 if ((newp+5 < cStartNew) || (newp+5 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+5, cStartNew, cEndNew); 1593 for (p = 0; p < 4; ++p) { 1594 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1595 } 1596 #endif 1597 /* C' tetrahedron: {b, f, c, a} */ 1598 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 1599 orntNew[0] = -3; 1600 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 1601 orntNew[1] = -2; 1602 coneNew[2] = fStartNew + (cone[0] - fStart)*4 + 3; 1603 orntNew[2] = ornt[0] < 0 ? (-(ornt[0]+1)+1)%3 : -((ornt[0]+1)%3+1); 1604 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 1605 orntNew[3] = -1; 1606 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 1607 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 1608 #if 1 1609 if ((newp+6 < cStartNew) || (newp+6 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+6, cStartNew, cEndNew); 1610 for (p = 0; p < 4; ++p) { 1611 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1612 } 1613 #endif 1614 /* D' tetrahedron: {f, e, d, a} */ 1615 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 1616 orntNew[0] = -3; 1617 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 1618 orntNew[1] = -3; 1619 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 1620 orntNew[2] = -2; 1621 coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3; 1622 orntNew[3] = ornt[2]; 1623 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 1624 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 1625 #if 1 1626 if ((newp+7 < cStartNew) || (newp+7 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+7, cStartNew, cEndNew); 1627 for (p = 0; p < 4; ++p) { 1628 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1629 } 1630 #endif 1631 } 1632 /* Split faces have 3 edges and the same cells as the parent */ 1633 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1634 ierr = PetscMalloc((2 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr); 1635 for (f = fStart; f < fEnd; ++f) { 1636 const PetscInt newp = fStartNew + (f - fStart)*4; 1637 const PetscInt *cone, *ornt, *support; 1638 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 1639 1640 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1641 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 1642 /* A triangle */ 1643 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 1644 orntNew[0] = ornt[0]; 1645 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 1646 orntNew[1] = -2; 1647 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 1648 orntNew[2] = ornt[2]; 1649 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1650 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1651 #if 1 1652 if ((newp+0 < fStartNew) || (newp+0 >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+0, fStartNew, fEndNew); 1653 for (p = 0; p < 3; ++p) { 1654 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1655 } 1656 #endif 1657 /* B triangle */ 1658 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 1659 orntNew[0] = ornt[0]; 1660 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 1661 orntNew[1] = ornt[1]; 1662 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 1663 orntNew[2] = -2; 1664 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1665 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1666 #if 1 1667 if ((newp+1 < fStartNew) || (newp+1 >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+1, fStartNew, fEndNew); 1668 for (p = 0; p < 3; ++p) { 1669 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1670 } 1671 #endif 1672 /* C triangle */ 1673 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 1674 orntNew[0] = -2; 1675 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 1676 orntNew[1] = ornt[1]; 1677 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 1678 orntNew[2] = ornt[2]; 1679 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1680 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1681 #if 1 1682 if ((newp+2 < fStartNew) || (newp+2 >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+2, fStartNew, fEndNew); 1683 for (p = 0; p < 3; ++p) { 1684 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1685 } 1686 #endif 1687 /* D triangle */ 1688 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 1689 orntNew[0] = 0; 1690 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 1691 orntNew[1] = 0; 1692 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 1693 orntNew[2] = 0; 1694 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1695 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1696 #if 1 1697 if ((newp+3 < fStartNew) || (newp+3 >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+3, fStartNew, fEndNew); 1698 for (p = 0; p < 3; ++p) { 1699 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1700 } 1701 #endif 1702 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1703 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1704 for (r = 0; r < 4; ++r) { 1705 for (s = 0; s < supportSize; ++s) { 1706 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1707 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1708 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1709 for (c = 0; c < coneSize; ++c) { 1710 if (cone[c] == f) break; 1711 } 1712 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : (ornt[c] < 0 ? faces[c*3+(-(ornt[c]+1)+1+3-r)%3] : faces[c*3+r])); 1713 } 1714 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 1715 #if 1 1716 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1717 for (p = 0; p < supportSize; ++p) { 1718 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew); 1719 } 1720 #endif 1721 } 1722 } 1723 /* Interior faces have 3 edges and 2 cells */ 1724 for (c = cStart; c < cEnd; ++c) { 1725 PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 1726 const PetscInt *cone, *ornt; 1727 PetscInt coneNew[3], orntNew[3]; 1728 PetscInt supportNew[2]; 1729 1730 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1731 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1732 /* Face A: {c, a, d} */ 1733 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+0)%3 : (ornt[0]+2)%3); 1734 orntNew[0] = ornt[0] < 0 ? -2 : 0; 1735 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+0)%3 : (ornt[1]+2)%3); 1736 orntNew[1] = ornt[1] < 0 ? -2 : 0; 1737 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+0)%3 : (ornt[2]+2)%3); 1738 orntNew[2] = ornt[2] < 0 ? -2 : 0; 1739 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1740 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1741 #if 1 1742 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1743 for (p = 0; p < 3; ++p) { 1744 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1745 } 1746 #endif 1747 supportNew[0] = (c - cStart)*8 + 0; 1748 supportNew[1] = (c - cStart)*8 + 0+4; 1749 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1750 #if 1 1751 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1752 for (p = 0; p < 2; ++p) { 1753 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 1754 } 1755 #endif 1756 ++newp; 1757 /* Face B: {a, b, e} */ 1758 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+2)%3 : (ornt[0]+0)%3); 1759 orntNew[0] = ornt[0] < 0 ? -2 : 0; 1760 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+2)%3 : (ornt[3]+0)%3); 1761 orntNew[1] = ornt[3] < 0 ? -2 : 0; 1762 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+1)%3 : (ornt[1]+1)%3); 1763 orntNew[2] = ornt[1] < 0 ? -2 : 0; 1764 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1765 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1766 #if 1 1767 if ((newp+1 < fStartNew) || (newp+1 >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+1, fStartNew, fEndNew); 1768 for (p = 0; p < 3; ++p) { 1769 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1770 } 1771 #endif 1772 supportNew[0] = (c - cStart)*8 + 1; 1773 supportNew[1] = (c - cStart)*8 + 1+4; 1774 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1775 #if 1 1776 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1777 for (p = 0; p < 2; ++p) { 1778 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 1779 } 1780 #endif 1781 ++newp; 1782 /* Face C: {c, f, b} */ 1783 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+2)%3 : (ornt[2]+0)%3); 1784 orntNew[0] = ornt[2] < 0 ? -2 : 0; 1785 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+0)%3 : (ornt[3]+2)%3); 1786 orntNew[1] = ornt[3] < 0 ? -2 : 0; 1787 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+1)%3 : (ornt[0]+1)%3); 1788 orntNew[2] = ornt[0] < 0 ? -2 : 0; 1789 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1790 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1791 #if 1 1792 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1793 for (p = 0; p < 3; ++p) { 1794 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1795 } 1796 #endif 1797 supportNew[0] = (c - cStart)*8 + 2; 1798 supportNew[1] = (c - cStart)*8 + 2+4; 1799 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1800 #if 1 1801 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1802 for (p = 0; p < 2; ++p) { 1803 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 1804 } 1805 #endif 1806 ++newp; 1807 /* Face D: {d, e, f} */ 1808 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+2)%3 : (ornt[1]+0)%3); 1809 orntNew[0] = ornt[1] < 0 ? -2 : 0; 1810 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+1)%3 : (ornt[3]+1)%3); 1811 orntNew[1] = ornt[3] < 0 ? -2 : 0; 1812 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+1)%3 : (ornt[2]+1)%3); 1813 orntNew[2] = ornt[2] < 0 ? -2 : 0; 1814 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1815 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1816 #if 1 1817 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1818 for (p = 0; p < 3; ++p) { 1819 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1820 } 1821 #endif 1822 supportNew[0] = (c - cStart)*8 + 3; 1823 supportNew[1] = (c - cStart)*8 + 3+4; 1824 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1825 #if 1 1826 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1827 for (p = 0; p < 2; ++p) { 1828 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 1829 } 1830 #endif 1831 ++newp; 1832 /* Face E: {d, f, a} */ 1833 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+1)%3 : (ornt[2]+1)%3); 1834 orntNew[0] = ornt[2] < 0 ? 0 : -2; 1835 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 1836 orntNew[1] = 0; 1837 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+0)%3 : (ornt[1]+2)%3); 1838 orntNew[2] = ornt[1] < 0 ? -2 : 0; 1839 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1840 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1841 #if 1 1842 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1843 for (p = 0; p < 3; ++p) { 1844 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1845 } 1846 #endif 1847 supportNew[0] = (c - cStart)*8 + 0+4; 1848 supportNew[1] = (c - cStart)*8 + 3+4; 1849 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1850 #if 1 1851 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1852 for (p = 0; p < 2; ++p) { 1853 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 1854 } 1855 #endif 1856 ++newp; 1857 /* Face F: {c, a, f} */ 1858 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+0)%3 : (ornt[0]+2)%3); 1859 orntNew[0] = ornt[0] < 0 ? -2 : 0; 1860 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 1861 orntNew[1] = -2; 1862 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+2)%3 : (ornt[2]+0)%3); 1863 orntNew[2] = ornt[1] < 0 ? 0 : -2; 1864 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1865 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1866 #if 1 1867 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1868 for (p = 0; p < 3; ++p) { 1869 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1870 } 1871 #endif 1872 supportNew[0] = (c - cStart)*8 + 0+4; 1873 supportNew[1] = (c - cStart)*8 + 2+4; 1874 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1875 #if 1 1876 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1877 for (p = 0; p < 2; ++p) { 1878 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 1879 } 1880 #endif 1881 ++newp; 1882 /* Face G: {e, a, f} */ 1883 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+1)%3 : (ornt[1]+1)%3); 1884 orntNew[0] = ornt[1] < 0 ? -2 : 0; 1885 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 1886 orntNew[1] = -2; 1887 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+1)%3 : (ornt[3]+1)%3); 1888 orntNew[2] = ornt[3] < 0 ? 0 : -2; 1889 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1890 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1891 #if 1 1892 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1893 for (p = 0; p < 3; ++p) { 1894 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1895 } 1896 #endif 1897 supportNew[0] = (c - cStart)*8 + 1+4; 1898 supportNew[1] = (c - cStart)*8 + 3+4; 1899 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1900 #if 1 1901 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1902 for (p = 0; p < 2; ++p) { 1903 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 1904 } 1905 #endif 1906 ++newp; 1907 /* Face H: {a, b, f} */ 1908 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+2)%3 : (ornt[0]+0)%3); 1909 orntNew[0] = ornt[0] < 0 ? -2 : 0; 1910 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+0)%3 : (ornt[3]+2)%3); 1911 orntNew[1] = ornt[3] < 0 ? 0 : -2; 1912 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 1913 orntNew[2] = 0; 1914 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1915 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1916 #if 1 1917 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1918 for (p = 0; p < 3; ++p) { 1919 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1920 } 1921 #endif 1922 supportNew[0] = (c - cStart)*8 + 1+4; 1923 supportNew[1] = (c - cStart)*8 + 2+4; 1924 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1925 #if 1 1926 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1927 for (p = 0; p < 2; ++p) { 1928 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 1929 } 1930 #endif 1931 ++newp; 1932 } 1933 /* Split Edges have 2 vertices and the same faces as the parent */ 1934 for (e = eStart; e < eEnd; ++e) { 1935 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 1936 1937 for (r = 0; r < 2; ++r) { 1938 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1939 const PetscInt *cone, *ornt, *support; 1940 PetscInt coneNew[2], coneSize, c, supportSize, s; 1941 1942 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 1943 coneNew[0] = vStartNew + (cone[0] - vStart); 1944 coneNew[1] = vStartNew + (cone[1] - vStart); 1945 coneNew[(r+1)%2] = newv; 1946 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1947 #if 1 1948 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 1949 for (p = 0; p < 2; ++p) { 1950 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 1951 } 1952 #endif 1953 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 1954 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 1955 for (s = 0; s < supportSize; ++s) { 1956 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1957 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1958 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1959 for (c = 0; c < coneSize; ++c) { 1960 if (cone[c] == e) break; 1961 } 1962 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 1963 } 1964 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1965 #if 1 1966 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 1967 for (p = 0; p < supportSize; ++p) { 1968 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 1969 } 1970 #endif 1971 } 1972 } 1973 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 1974 for (f = fStart; f < fEnd; ++f) { 1975 const PetscInt *cone, *ornt, *support; 1976 PetscInt coneSize, supportSize, s; 1977 1978 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1979 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1980 for (r = 0; r < 3; ++r) { 1981 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 1982 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 1983 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 1984 -1, -1, 1, 6, 0, 4, 1985 2, 5, 3, 4, -1, -1, 1986 -1, -1, 3, 6, 2, 7}; 1987 1988 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1989 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 1990 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 1991 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1992 #if 1 1993 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 1994 for (p = 0; p < 2; ++p) { 1995 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 1996 } 1997 #endif 1998 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 1999 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 2000 for (s = 0; s < supportSize; ++s) { 2001 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2002 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2003 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2004 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 2005 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 2006 er = ornt[c] < 0 ? (-(ornt[c]+1) + 2-r)%3 : (ornt[c] + r)%3; 2007 if (er == eint[c]) { 2008 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 2009 } else { 2010 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 2011 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 2012 } 2013 } 2014 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2015 #if 1 2016 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2017 for (p = 0; p < intFaces; ++p) { 2018 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 2019 } 2020 #endif 2021 } 2022 } 2023 /* Interior edges have 2 vertices and 4 faces */ 2024 for (c = cStart; c < cEnd; ++c) { 2025 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2026 const PetscInt *cone, *ornt, *fcone; 2027 PetscInt coneNew[2], supportNew[4], find; 2028 2029 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2030 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2031 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 2032 find = GetTriEdge_Static(ornt[0], 0); 2033 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2034 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 2035 find = GetTriEdge_Static(ornt[2], 1); 2036 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2037 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2038 #if 1 2039 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2040 for (p = 0; p < 2; ++p) { 2041 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 2042 } 2043 #endif 2044 supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2045 supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2046 supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2047 supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2048 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2049 #if 1 2050 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2051 for (p = 0; p < 4; ++p) { 2052 if ((supportNew[p] < fStartNew) || (supportNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportNew[p], fStartNew, fEndNew); 2053 } 2054 #endif 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] = eStartNew + (support[s] - eStart)*2 + r; 2070 } 2071 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2072 #if 1 2073 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), 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] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 2076 } 2077 #endif 2078 } 2079 /* Edge vertices have 2 + face*2 + 0/1 supports */ 2080 for (e = eStart; e < eEnd; ++e) { 2081 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 2082 const PetscInt *cone, *support; 2083 PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 2084 2085 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 2086 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2087 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 2088 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 2089 for (s = 0; s < size; ++s) { 2090 PetscInt r = 0; 2091 2092 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2093 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2094 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 2095 supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 2096 supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 2097 } 2098 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2099 for (s = 0; s < starSize*2; s += 2) { 2100 const PetscInt *cone, *ornt; 2101 PetscInt e01, e23; 2102 2103 if ((star[s] >= cStart) && (star[s] < cEnd)) { 2104 /* Check edge 0-1 */ 2105 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2106 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2107 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 2108 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 2109 /* Check edge 2-3 */ 2110 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2111 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2112 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 2113 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 2114 if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 2115 } 2116 } 2117 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2118 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2119 #if 1 2120 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2121 for (p = 0; p < 2+size*2+cellSize; ++p) { 2122 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 2123 } 2124 #endif 2125 } 2126 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2127 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 2128 break; 2129 case 7: 2130 /* Hybrid Simplicial 3D */ 2131 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 2132 /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 2133 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 2134 for (c = cStart; c < cMax; ++c) { 2135 const PetscInt newp = cStartNew + (c - cStart)*8; 2136 const PetscInt *cone, *ornt; 2137 PetscInt coneNew[4], orntNew[4]; 2138 2139 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2140 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2141 /* A tetrahedron: {0, a, c, d} */ 2142 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 2143 orntNew[0] = ornt[0]; 2144 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 2145 orntNew[1] = ornt[1]; 2146 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 2147 orntNew[2] = ornt[2]; 2148 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 2149 orntNew[3] = 0; 2150 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2151 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2152 #if 1 2153 if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cMaxNew); 2154 for (p = 0; p < 4; ++p) { 2155 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 2156 } 2157 #endif 2158 /* B tetrahedron: {a, 1, b, e} */ 2159 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 2160 orntNew[0] = ornt[0]; 2161 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 2162 orntNew[1] = ornt[1]; 2163 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 2164 orntNew[2] = 0; 2165 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 2166 orntNew[3] = ornt[3]; 2167 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2168 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2169 #if 1 2170 if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cMaxNew); 2171 for (p = 0; p < 4; ++p) { 2172 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 2173 } 2174 #endif 2175 /* C tetrahedron: {c, b, 2, f} */ 2176 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 2177 orntNew[0] = ornt[0]; 2178 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 2179 orntNew[1] = 0; 2180 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 2181 orntNew[2] = ornt[2]; 2182 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 2183 orntNew[3] = ornt[3]; 2184 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2185 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2186 #if 1 2187 if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cMaxNew); 2188 for (p = 0; p < 4; ++p) { 2189 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 2190 } 2191 #endif 2192 /* D tetrahedron: {d, e, f, 3} */ 2193 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 2194 orntNew[0] = 0; 2195 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 2196 orntNew[1] = ornt[1]; 2197 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 2198 orntNew[2] = ornt[2]; 2199 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 2200 orntNew[3] = ornt[3]; 2201 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2202 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2203 #if 1 2204 if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cMaxNew); 2205 for (p = 0; p < 4; ++p) { 2206 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 2207 } 2208 #endif 2209 /* A' tetrahedron: {d, a, c, f} */ 2210 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 2211 orntNew[0] = -3; 2212 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 2213 orntNew[1] = 0; 2214 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + 3; 2215 orntNew[2] = ornt[2] < 0 ? -((-(ornt[2]+1)+2)%3+1) : (ornt[2]+2)%3; 2216 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 2217 orntNew[3] = 0; 2218 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 2219 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 2220 #if 1 2221 if ((newp+4 < cStartNew) || (newp+4 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+4, cStartNew, cMaxNew); 2222 for (p = 0; p < 4; ++p) { 2223 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 2224 } 2225 #endif 2226 /* B' tetrahedron: {e, b, a, f} */ 2227 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 2228 orntNew[0] = -3; 2229 coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3; 2230 orntNew[1] = ornt[3] < 0 ? -((-(ornt[3]+1)+1)%3+1) : (ornt[3]+1)%3; 2231 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 2232 orntNew[2] = 0; 2233 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 2234 orntNew[3] = 0; 2235 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 2236 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 2237 #if 1 2238 if ((newp+5 < cStartNew) || (newp+5 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+5, cStartNew, cMaxNew); 2239 for (p = 0; p < 4; ++p) { 2240 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 2241 } 2242 #endif 2243 /* C' tetrahedron: {b, f, c, a} */ 2244 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 2245 orntNew[0] = -3; 2246 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 2247 orntNew[1] = -2; 2248 coneNew[2] = fStartNew + (cone[0] - fStart)*4 + 3; 2249 orntNew[2] = ornt[0] < 0 ? (-(ornt[0]+1)+1)%3 : -((ornt[0]+1)%3+1); 2250 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 2251 orntNew[3] = -1; 2252 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 2253 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 2254 #if 1 2255 if ((newp+6 < cStartNew) || (newp+6 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+6, cStartNew, cMaxNew); 2256 for (p = 0; p < 4; ++p) { 2257 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 2258 } 2259 #endif 2260 /* D' tetrahedron: {f, e, d, a} */ 2261 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 2262 orntNew[0] = -3; 2263 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 2264 orntNew[1] = -3; 2265 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 2266 orntNew[2] = -2; 2267 coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3; 2268 orntNew[3] = ornt[2]; 2269 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 2270 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 2271 #if 1 2272 if ((newp+7 < cStartNew) || (newp+7 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+7, cStartNew, cMaxNew); 2273 for (p = 0; p < 4; ++p) { 2274 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 2275 } 2276 #endif 2277 } 2278 /* Hybrid cells have 5 faces */ 2279 for (c = cMax; c < cEnd; ++c) { 2280 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4; 2281 const PetscInt *cone, *ornt; 2282 PetscInt coneNew[5], orntNew[5]; 2283 2284 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2285 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2286 for (r = 0; r < 3; ++r) { 2287 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 2288 orntNew[0] = ornt[0]; 2289 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 2290 orntNew[1] = ornt[1]; 2291 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriSubface_Static(ornt[0], (r+2)%3)] - fMax)*2 + (ornt[2+GetTriSubface_Static(ornt[0], (r+2)%3)] < 0 ? 0 : 1); 2292 orntNew[2] = 0; 2293 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriSubface_Static(ornt[0], r)] - fMax)*2 + (ornt[2+GetTriSubface_Static(ornt[0], r)] < 0 ? 1 : 0); 2294 orntNew[3] = 0; 2295 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 2296 orntNew[4] = 0; 2297 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 2298 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 2299 #if 1 2300 if ((newp+r < cMaxNew) || (newp+r >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", newp+r, cMaxNew, cEndNew); 2301 for (p = 0; p < 2; ++p) { 2302 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 2303 } 2304 for (p = 2; p < 5; ++p) { 2305 if ((coneNew[p] < fMaxNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", coneNew[p], fMaxNew, fEndNew); 2306 } 2307 #endif 2308 } 2309 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 2310 orntNew[0] = 0; 2311 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 2312 orntNew[1] = 0; 2313 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 2314 orntNew[2] = 0; 2315 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 2316 orntNew[3] = 0; 2317 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 2318 orntNew[4] = 0; 2319 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2320 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2321 #if 1 2322 if ((newp+3 < cMaxNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", newp+3, cMaxNew, cEndNew); 2323 for (p = 0; p < 2; ++p) { 2324 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 2325 } 2326 for (p = 2; p < 5; ++p) { 2327 if ((coneNew[p] < fMaxNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", coneNew[p], fMaxNew, fEndNew); 2328 } 2329 #endif 2330 } 2331 /* Split faces have 3 edges and the same cells as the parent */ 2332 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2333 ierr = PetscMalloc((2 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr); 2334 for (f = fStart; f < fMax; ++f) { 2335 const PetscInt newp = fStartNew + (f - fStart)*4; 2336 const PetscInt *cone, *ornt, *support; 2337 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 2338 2339 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2340 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2341 /* A triangle */ 2342 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 2343 orntNew[0] = ornt[0]; 2344 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 2345 orntNew[1] = -2; 2346 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 2347 orntNew[2] = ornt[2]; 2348 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2349 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2350 #if 1 2351 if ((newp+0 < fStartNew) || (newp+0 >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+0, fStartNew, fMaxNew); 2352 for (p = 0; p < 3; ++p) { 2353 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 2354 } 2355 #endif 2356 /* B triangle */ 2357 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 2358 orntNew[0] = ornt[0]; 2359 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 2360 orntNew[1] = ornt[1]; 2361 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 2362 orntNew[2] = -2; 2363 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2364 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2365 #if 1 2366 if ((newp+1 < fStartNew) || (newp+1 >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+1, fStartNew, fMaxNew); 2367 for (p = 0; p < 3; ++p) { 2368 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 2369 } 2370 #endif 2371 /* C triangle */ 2372 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 2373 orntNew[0] = -2; 2374 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 2375 orntNew[1] = ornt[1]; 2376 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 2377 orntNew[2] = ornt[2]; 2378 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2379 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2380 #if 1 2381 if ((newp+2 < fStartNew) || (newp+2 >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+2, fStartNew, fMaxNew); 2382 for (p = 0; p < 3; ++p) { 2383 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 2384 } 2385 #endif 2386 /* D triangle */ 2387 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 2388 orntNew[0] = 0; 2389 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 2390 orntNew[1] = 0; 2391 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 2392 orntNew[2] = 0; 2393 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2394 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2395 #if 1 2396 if ((newp+3 < fStartNew) || (newp+3 >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+3, fStartNew, fMaxNew); 2397 for (p = 0; p < 3; ++p) { 2398 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 2399 } 2400 #endif 2401 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2402 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2403 for (r = 0; r < 4; ++r) { 2404 for (s = 0; s < supportSize; ++s) { 2405 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2406 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2407 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2408 for (c = 0; c < coneSize; ++c) { 2409 if (cone[c] == f) break; 2410 } 2411 if (support[s] < cMax) { 2412 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : (ornt[c] < 0 ? faces[c*3+(-(ornt[c]+1)+1+3-r)%3] : faces[c*3+r])); 2413 } else { 2414 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + r; 2415 } 2416 } 2417 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 2418 #if 1 2419 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2420 for (p = 0; p < supportSize; ++p) { 2421 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior or hybrid cell [%d, %d)", supportRef[p], cStartNew, cEndNew); 2422 } 2423 #endif 2424 } 2425 } 2426 /* Interior cell faces have 3 edges and 2 cells */ 2427 for (c = cStart; c < cMax; ++c) { 2428 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 2429 const PetscInt *cone, *ornt; 2430 PetscInt coneNew[3], orntNew[3]; 2431 PetscInt supportNew[2]; 2432 2433 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2434 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2435 /* Face A: {c, a, d} */ 2436 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+0)%3 : (ornt[0]+2)%3); 2437 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2438 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+0)%3 : (ornt[1]+2)%3); 2439 orntNew[1] = ornt[1] < 0 ? -2 : 0; 2440 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+0)%3 : (ornt[2]+2)%3); 2441 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2442 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2443 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2444 #if 1 2445 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2446 for (p = 0; p < 3; ++p) { 2447 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 2448 } 2449 #endif 2450 supportNew[0] = (c - cStart)*8 + 0; 2451 supportNew[1] = (c - cStart)*8 + 0+4; 2452 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2453 #if 1 2454 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2455 for (p = 0; p < 2; ++p) { 2456 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew); 2457 } 2458 #endif 2459 ++newp; 2460 /* Face B: {a, b, e} */ 2461 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+2)%3 : (ornt[0]+0)%3); 2462 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2463 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+2)%3 : (ornt[3]+0)%3); 2464 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2465 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+1)%3 : (ornt[1]+1)%3); 2466 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2467 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2468 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2469 #if 1 2470 if ((newp+1 < fStartNew) || (newp+1 >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+1, fStartNew, fMaxNew); 2471 for (p = 0; p < 3; ++p) { 2472 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 2473 } 2474 #endif 2475 supportNew[0] = (c - cStart)*8 + 1; 2476 supportNew[1] = (c - cStart)*8 + 1+4; 2477 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2478 #if 1 2479 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2480 for (p = 0; p < 2; ++p) { 2481 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew); 2482 } 2483 #endif 2484 ++newp; 2485 /* Face C: {c, f, b} */ 2486 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+2)%3 : (ornt[2]+0)%3); 2487 orntNew[0] = ornt[2] < 0 ? -2 : 0; 2488 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+0)%3 : (ornt[3]+2)%3); 2489 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2490 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+1)%3 : (ornt[0]+1)%3); 2491 orntNew[2] = ornt[0] < 0 ? -2 : 0; 2492 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2493 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2494 #if 1 2495 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2496 for (p = 0; p < 3; ++p) { 2497 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 2498 } 2499 #endif 2500 supportNew[0] = (c - cStart)*8 + 2; 2501 supportNew[1] = (c - cStart)*8 + 2+4; 2502 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2503 #if 1 2504 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2505 for (p = 0; p < 2; ++p) { 2506 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew); 2507 } 2508 #endif 2509 ++newp; 2510 /* Face D: {d, e, f} */ 2511 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+2)%3 : (ornt[1]+0)%3); 2512 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2513 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+1)%3 : (ornt[3]+1)%3); 2514 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2515 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+1)%3 : (ornt[2]+1)%3); 2516 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2517 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2518 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2519 #if 1 2520 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2521 for (p = 0; p < 3; ++p) { 2522 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 2523 } 2524 #endif 2525 supportNew[0] = (c - cStart)*8 + 3; 2526 supportNew[1] = (c - cStart)*8 + 3+4; 2527 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2528 #if 1 2529 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2530 for (p = 0; p < 2; ++p) { 2531 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew); 2532 } 2533 #endif 2534 ++newp; 2535 /* Face E: {d, f, a} */ 2536 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+1)%3 : (ornt[2]+1)%3); 2537 orntNew[0] = ornt[2] < 0 ? 0 : -2; 2538 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2539 orntNew[1] = 0; 2540 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+0)%3 : (ornt[1]+2)%3); 2541 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2542 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2543 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2544 #if 1 2545 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2546 for (p = 0; p < 3; ++p) { 2547 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 2548 } 2549 #endif 2550 supportNew[0] = (c - cStart)*8 + 0+4; 2551 supportNew[1] = (c - cStart)*8 + 3+4; 2552 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2553 #if 1 2554 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2555 for (p = 0; p < 2; ++p) { 2556 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew); 2557 } 2558 #endif 2559 ++newp; 2560 /* Face F: {c, a, f} */ 2561 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+0)%3 : (ornt[0]+2)%3); 2562 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2563 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2564 orntNew[1] = -2; 2565 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+2)%3 : (ornt[2]+0)%3); 2566 orntNew[2] = ornt[1] < 0 ? 0 : -2; 2567 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2568 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2569 #if 1 2570 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2571 for (p = 0; p < 3; ++p) { 2572 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 2573 } 2574 #endif 2575 supportNew[0] = (c - cStart)*8 + 0+4; 2576 supportNew[1] = (c - cStart)*8 + 2+4; 2577 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2578 #if 1 2579 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2580 for (p = 0; p < 2; ++p) { 2581 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew); 2582 } 2583 #endif 2584 ++newp; 2585 /* Face G: {e, a, f} */ 2586 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+1)%3 : (ornt[1]+1)%3); 2587 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2588 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2589 orntNew[1] = -2; 2590 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+1)%3 : (ornt[3]+1)%3); 2591 orntNew[2] = ornt[3] < 0 ? 0 : -2; 2592 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2593 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2594 #if 1 2595 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2596 for (p = 0; p < 3; ++p) { 2597 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 2598 } 2599 #endif 2600 supportNew[0] = (c - cStart)*8 + 1+4; 2601 supportNew[1] = (c - cStart)*8 + 3+4; 2602 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2603 #if 1 2604 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2605 for (p = 0; p < 2; ++p) { 2606 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew); 2607 } 2608 #endif 2609 ++newp; 2610 /* Face H: {a, b, f} */ 2611 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+2)%3 : (ornt[0]+0)%3); 2612 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2613 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+0)%3 : (ornt[3]+2)%3); 2614 orntNew[1] = ornt[3] < 0 ? 0 : -2; 2615 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2616 orntNew[2] = 0; 2617 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2618 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2619 #if 1 2620 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2621 for (p = 0; p < 3; ++p) { 2622 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 2623 } 2624 #endif 2625 supportNew[0] = (c - cStart)*8 + 1+4; 2626 supportNew[1] = (c - cStart)*8 + 2+4; 2627 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2628 #if 1 2629 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2630 for (p = 0; p < 2; ++p) { 2631 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew); 2632 } 2633 #endif 2634 ++newp; 2635 } 2636 /* Hybrid split faces have 4 edges and same cells */ 2637 for (f = fMax; f < fEnd; ++f) { 2638 const PetscInt *cone, *ornt, *support; 2639 PetscInt coneNew[4], orntNew[4]; 2640 PetscInt supportNew[2], size, s, c; 2641 2642 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2643 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2644 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2645 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2646 for (r = 0; r < 2; ++r) { 2647 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 2648 2649 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 2650 orntNew[0] = ornt[0]; 2651 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 2652 orntNew[1] = ornt[1]; 2653 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 2654 orntNew[2+r] = 0; 2655 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 2656 orntNew[3-r] = 0; 2657 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2658 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2659 #if 1 2660 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 2661 for (p = 0; p < 2; ++p) { 2662 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 2663 } 2664 for (p = 2; p < 4; ++p) { 2665 if ((coneNew[p] < eMaxNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", coneNew[p], eMaxNew, eEndNew); 2666 } 2667 #endif 2668 for (s = 0; s < size; ++s) { 2669 const PetscInt *coneCell, *orntCell; 2670 2671 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 2672 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 2673 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 2674 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 2675 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + GetTriSubface_Static(orntCell[c], (c-2+r)%3); 2676 } 2677 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2678 #if 1 2679 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 2680 for (p = 0; p < size; ++p) { 2681 if ((supportNew[p] < cMaxNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", supportNew[p], cMaxNew, cEndNew); 2682 } 2683 #endif 2684 } 2685 } 2686 /* Hybrid cell faces have 4 edges and 2 cells */ 2687 for (c = cMax; c < cEnd; ++c) { 2688 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 2689 const PetscInt *cone, *ornt; 2690 PetscInt coneNew[4], orntNew[4]; 2691 PetscInt supportNew[2]; 2692 2693 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2694 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2695 for (r = 0; r < 3; ++r) { 2696 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], (r+2)%3); 2697 orntNew[0] = 0; 2698 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], (r+2)%3); 2699 orntNew[1] = 0; 2700 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+GetTriSubface_Static(ornt[0], (r+2)%3)] - fMax); 2701 orntNew[2] = 0; 2702 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+GetTriSubface_Static(ornt[0], r)] - fMax); 2703 orntNew[3] = 0; 2704 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 2705 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 2706 #if 1 2707 if ((newp+r < fMaxNew) || (newp+r >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp+r, fMaxNew, fEndNew); 2708 for (p = 0; p < 2; ++p) { 2709 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 2710 } 2711 for (p = 2; p < 4; ++p) { 2712 if ((coneNew[p] < eMaxNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", coneNew[p], eMaxNew, eEndNew); 2713 } 2714 #endif 2715 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 2716 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 2717 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 2718 #if 1 2719 if ((newp+r < fMaxNew) || (newp+r >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp+r, fMaxNew, fEndNew); 2720 for (p = 0; p < 2; ++p) { 2721 if ((supportNew[p] < cMaxNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", supportNew[p], cMaxNew, cEndNew); 2722 } 2723 #endif 2724 } 2725 } 2726 /* Interior split edges have 2 vertices and the same faces as the parent */ 2727 for (e = eStart; e < eMax; ++e) { 2728 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 2729 2730 for (r = 0; r < 2; ++r) { 2731 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 2732 const PetscInt *cone, *ornt, *support; 2733 PetscInt coneNew[2], coneSize, c, supportSize, s; 2734 2735 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 2736 coneNew[0] = vStartNew + (cone[0] - vStart); 2737 coneNew[1] = vStartNew + (cone[1] - vStart); 2738 coneNew[(r+1)%2] = newv; 2739 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2740 #if 1 2741 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2742 for (p = 0; p < 2; ++p) { 2743 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 2744 } 2745 #endif 2746 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 2747 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2748 for (s = 0; s < supportSize; ++s) { 2749 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2750 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2751 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2752 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 2753 if (support[s] < fMax) { 2754 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 2755 } else { 2756 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 2757 } 2758 } 2759 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2760 #if 1 2761 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2762 for (p = 0; p < supportSize; ++p) { 2763 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior or hybrid face [%d, %d)", supportRef[p], fStartNew, fEndNew); 2764 } 2765 #endif 2766 } 2767 } 2768 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 2769 for (f = fStart; f < fMax; ++f) { 2770 const PetscInt *cone, *ornt, *support; 2771 PetscInt coneSize, supportSize, s; 2772 2773 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2774 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2775 for (r = 0; r < 3; ++r) { 2776 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 2777 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 2778 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 2779 -1, -1, 1, 6, 0, 4, 2780 2, 5, 3, 4, -1, -1, 2781 -1, -1, 3, 6, 2, 7}; 2782 2783 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2784 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 2785 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 2786 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2787 #if 1 2788 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2789 for (p = 0; p < 2; ++p) { 2790 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 2791 } 2792 #endif 2793 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 2794 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 2795 for (s = 0; s < supportSize; ++s) { 2796 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2797 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2798 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2799 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 2800 if (support[s] < cMax) { 2801 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 2802 er = ornt[c] < 0 ? (-(ornt[c]+1) + 2-r)%3 : (ornt[c] + r)%3; 2803 if (er == eint[c]) { 2804 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 2805 } else { 2806 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 2807 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 2808 } 2809 } else { 2810 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r+1)%3; 2811 } 2812 } 2813 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2814 #if 1 2815 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2816 for (p = 0; p < intFaces; ++p) { 2817 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior or hybrid face [%d, %d)", supportRef[p], fStartNew, fEndNew); 2818 } 2819 #endif 2820 } 2821 } 2822 /* Interior cell edges have 2 vertices and 4 faces */ 2823 for (c = cStart; c < cMax; ++c) { 2824 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2825 const PetscInt *cone, *ornt, *fcone; 2826 PetscInt coneNew[2], supportNew[4], find; 2827 2828 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2829 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2830 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 2831 find = GetTriEdge_Static(ornt[0], 0); 2832 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2833 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 2834 find = GetTriEdge_Static(ornt[2], 1); 2835 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2836 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2837 #if 1 2838 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2839 for (p = 0; p < 2; ++p) { 2840 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 2841 } 2842 #endif 2843 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 2844 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 2845 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 2846 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 2847 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2848 #if 1 2849 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2850 for (p = 0; p < 4; ++p) { 2851 if ((supportNew[p] < fStartNew) || (supportNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportNew[p], fStartNew, fMaxNew); 2852 } 2853 #endif 2854 } 2855 /* Hybrid edges have two vertices and the same faces */ 2856 for (e = eMax; e < eEnd; ++e) { 2857 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 2858 const PetscInt *cone, *support, *fcone; 2859 PetscInt coneNew[2], size, fsize, s; 2860 2861 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 2862 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 2863 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2864 coneNew[0] = vStartNew + (cone[0] - vStart); 2865 coneNew[1] = vStartNew + (cone[1] - vStart); 2866 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2867 #if 1 2868 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 2869 for (p = 0; p < 2; ++p) { 2870 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 2871 } 2872 #endif 2873 for (s = 0; s < size; ++s) { 2874 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 2875 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 2876 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 2877 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 2878 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 2879 } 2880 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2881 #if 1 2882 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 2883 for (p = 0; p < size; ++p) { 2884 if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", supportRef[p], fMaxNew, fEndNew); 2885 } 2886 #endif 2887 } 2888 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 2889 for (f = fMax; f < fEnd; ++f) { 2890 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 2891 const PetscInt *cone, *support, *ccone; 2892 PetscInt coneNew[2], size, csize, s; 2893 2894 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2895 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2896 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2897 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 2898 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 2899 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2900 #if 1 2901 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 2902 for (p = 0; p < 2; ++p) { 2903 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 2904 } 2905 #endif 2906 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 2907 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 2908 for (s = 0; s < size; ++s) { 2909 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 2910 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 2911 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 2912 if ((c < 2) || (c >= csize)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Hybrid face %d is not in cone of hybrid cell %d", f, support[s]); 2913 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-2)%3; 2914 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3; 2915 } 2916 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2917 #if 1 2918 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 2919 for (p = 0; p < 2+size*2; ++p) { 2920 if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", supportRef[p], fMaxNew, fEndNew); 2921 } 2922 #endif 2923 } 2924 /* Interior vertices have identical supports */ 2925 for (v = vStart; v < vEnd; ++v) { 2926 const PetscInt newp = vStartNew + (v - vStart); 2927 const PetscInt *support, *cone; 2928 PetscInt size, s; 2929 2930 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2931 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2932 for (s = 0; s < size; ++s) { 2933 PetscInt r = 0; 2934 2935 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2936 if (cone[1] == v) r = 1; 2937 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 2938 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 2939 } 2940 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2941 #if 1 2942 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2943 for (p = 0; p < size; ++p) { 2944 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior or hybrid edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 2945 } 2946 #endif 2947 } 2948 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 2949 for (e = eStart; e < eMax; ++e) { 2950 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 2951 const PetscInt *cone, *support; 2952 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 2953 2954 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 2955 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2956 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 2957 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 2958 for (s = 0; s < size; ++s) { 2959 PetscInt r = 0; 2960 2961 if (support[s] < fMax) { 2962 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2963 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2964 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 2965 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 2966 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 2967 faceSize += 2; 2968 } else { 2969 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 2970 ++faceSize; 2971 } 2972 } 2973 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2974 for (s = 0; s < starSize*2; s += 2) { 2975 const PetscInt *cone, *ornt; 2976 PetscInt e01, e23; 2977 2978 if ((star[s] >= cStart) && (star[s] < cMax)) { 2979 /* Check edge 0-1 */ 2980 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2981 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2982 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 2983 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 2984 /* Check edge 2-3 */ 2985 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2986 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2987 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 2988 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 2989 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 2990 } 2991 } 2992 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2993 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2994 #if 1 2995 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2996 for (p = 0; p < 2+faceSize+cellSize; ++p) { 2997 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior or hybrid edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 2998 } 2999 #endif 3000 } 3001 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3002 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 3003 break; 3004 case 6: 3005 /* Hex 3D */ 3006 /* 3007 Bottom (viewed from top) Top 3008 1---------2---------2 7---------2---------6 3009 | | | | | | 3010 | B 2 C | | H 2 G | 3011 | | | | | | 3012 3----3----0----1----1 3----3----0----1----1 3013 | | | | | | 3014 | A 0 D | | E 0 F | 3015 | | | | | | 3016 0---------0---------3 4---------0---------5 3017 */ 3018 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 3019 for (c = cStart; c < cEnd; ++c) { 3020 const PetscInt newp = (c - cStart)*8; 3021 const PetscInt *cone, *ornt; 3022 PetscInt coneNew[6], orntNew[6]; 3023 3024 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3025 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3026 /* A hex */ 3027 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 3028 orntNew[0] = ornt[0]; 3029 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3030 orntNew[1] = 0; 3031 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 3032 orntNew[2] = ornt[2]; 3033 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3034 orntNew[3] = 0; 3035 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3036 orntNew[4] = 0; 3037 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 3038 orntNew[5] = ornt[5]; 3039 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3040 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3041 #if 1 3042 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew); 3043 for (p = 0; p < 6; ++p) { 3044 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 3045 } 3046 #endif 3047 /* B hex */ 3048 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 3049 orntNew[0] = ornt[0]; 3050 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3051 orntNew[1] = 0; 3052 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3053 orntNew[2] = -3; 3054 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 3055 orntNew[3] = ornt[3]; 3056 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3057 orntNew[4] = 0; 3058 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 3059 orntNew[5] = ornt[5]; 3060 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3061 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3062 #if 1 3063 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew); 3064 for (p = 0; p < 6; ++p) { 3065 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 3066 } 3067 #endif 3068 /* C hex */ 3069 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 3070 orntNew[0] = ornt[0]; 3071 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3072 orntNew[1] = 0; 3073 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3074 orntNew[2] = 0; 3075 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 3076 orntNew[3] = ornt[3]; 3077 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 3078 orntNew[4] = ornt[4]; 3079 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3080 orntNew[5] = -3; 3081 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3082 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3083 #if 1 3084 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew); 3085 for (p = 0; p < 6; ++p) { 3086 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 3087 } 3088 #endif 3089 /* D hex */ 3090 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 3091 orntNew[0] = ornt[0]; 3092 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3093 orntNew[1] = 0; 3094 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 3095 orntNew[2] = ornt[2]; 3096 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3097 orntNew[3] = -3; 3098 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 3099 orntNew[4] = ornt[4]; 3100 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3101 orntNew[5] = -3; 3102 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3103 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3104 #if 1 3105 if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew); 3106 for (p = 0; p < 6; ++p) { 3107 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 3108 } 3109 #endif 3110 /* E hex */ 3111 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3112 orntNew[0] = -3; 3113 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 3114 orntNew[1] = ornt[1]; 3115 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 3116 orntNew[2] = ornt[2]; 3117 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3118 orntNew[3] = 0; 3119 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3120 orntNew[4] = 0; 3121 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 3122 orntNew[5] = ornt[5]; 3123 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3124 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3125 #if 1 3126 if ((newp+4 < cStartNew) || (newp+4 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+4, cStartNew, cEndNew); 3127 for (p = 0; p < 6; ++p) { 3128 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 3129 } 3130 #endif 3131 /* F hex */ 3132 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3133 orntNew[0] = -3; 3134 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 3135 orntNew[1] = ornt[1]; 3136 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 3137 orntNew[2] = ornt[2]; 3138 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3139 orntNew[3] = 0; 3140 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 3141 orntNew[4] = ornt[4]; 3142 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3143 orntNew[5] = -3; 3144 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3145 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3146 #if 1 3147 if ((newp+5 < cStartNew) || (newp+5 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+5, cStartNew, cEndNew); 3148 for (p = 0; p < 6; ++p) { 3149 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 3150 } 3151 #endif 3152 /* G hex */ 3153 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3154 orntNew[0] = -3; 3155 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 3156 orntNew[1] = ornt[1]; 3157 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3158 orntNew[2] = -3; 3159 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 3160 orntNew[3] = ornt[3]; 3161 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 3162 orntNew[4] = ornt[4]; 3163 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3164 orntNew[5] = 0; 3165 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3166 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3167 #if 1 3168 if ((newp+6 < cStartNew) || (newp+6 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+6, cStartNew, cEndNew); 3169 for (p = 0; p < 6; ++p) { 3170 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 3171 } 3172 #endif 3173 /* H hex */ 3174 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3175 orntNew[0] = -3; 3176 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 3177 orntNew[1] = ornt[1]; 3178 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3179 orntNew[2] = -3; 3180 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 3181 orntNew[3] = ornt[3]; 3182 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3183 orntNew[4] = -3; 3184 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 3185 orntNew[5] = ornt[5]; 3186 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3187 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3188 #if 1 3189 if ((newp+7 < cStartNew) || (newp+7 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+7, cStartNew, cEndNew); 3190 for (p = 0; p < 6; ++p) { 3191 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 3192 } 3193 #endif 3194 } 3195 /* Split faces have 4 edges and the same cells as the parent */ 3196 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3197 ierr = PetscMalloc((4 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr); 3198 for (f = fStart; f < fEnd; ++f) { 3199 for (r = 0; r < 4; ++r) { 3200 /* TODO: This can come from GetFaces_Internal() */ 3201 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}; 3202 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 3203 const PetscInt *cone, *ornt, *support; 3204 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 3205 3206 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3207 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3208 coneNew[0] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 3209 orntNew[0] = ornt[(r+3)%4]; 3210 coneNew[1] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 3211 orntNew[1] = ornt[r]; 3212 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 3213 orntNew[2] = 0; 3214 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 3215 orntNew[3] = -2; 3216 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3217 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3218 #if 1 3219 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3220 for (p = 0; p < 4; ++p) { 3221 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3222 } 3223 #endif 3224 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3225 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3226 for (s = 0; s < supportSize; ++s) { 3227 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3228 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3229 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3230 for (c = 0; c < coneSize; ++c) { 3231 if (cone[c] == f) break; 3232 } 3233 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubface_Static(ornt[c], r)]; 3234 } 3235 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3236 #if 1 3237 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3238 for (p = 0; p < supportSize; ++p) { 3239 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew); 3240 } 3241 #endif 3242 } 3243 } 3244 /* Interior faces have 4 edges and 2 cells */ 3245 for (c = cStart; c < cEnd; ++c) { 3246 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}; 3247 const PetscInt *cone, *ornt; 3248 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 3249 3250 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3251 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3252 /* A-D face */ 3253 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 3254 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 3255 orntNew[0] = -2; 3256 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 3257 orntNew[1] = 0; 3258 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3259 orntNew[2] = 0; 3260 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3261 orntNew[3] = -2; 3262 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3263 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3264 #if 1 3265 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3266 for (p = 0; p < 4; ++p) { 3267 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3268 } 3269 #endif 3270 /* C-D face */ 3271 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 3272 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 3273 orntNew[0] = -2; 3274 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 3275 orntNew[1] = 0; 3276 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3277 orntNew[2] = 0; 3278 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3279 orntNew[3] = -2; 3280 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3281 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3282 #if 1 3283 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3284 for (p = 0; p < 4; ++p) { 3285 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3286 } 3287 #endif 3288 /* B-C face */ 3289 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 3290 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 3291 orntNew[0] = -2; 3292 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 3293 orntNew[1] = 0; 3294 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3295 orntNew[2] = 0; 3296 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3297 orntNew[3] = -2; 3298 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3299 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3300 #if 1 3301 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3302 for (p = 0; p < 4; ++p) { 3303 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3304 } 3305 #endif 3306 /* A-B face */ 3307 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 3308 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 3309 orntNew[0] = -2; 3310 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 3311 orntNew[1] = 0; 3312 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3313 orntNew[2] = 0; 3314 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3315 orntNew[3] = -2; 3316 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3317 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3318 #if 1 3319 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3320 for (p = 0; p < 4; ++p) { 3321 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3322 } 3323 #endif 3324 /* E-F face */ 3325 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 3326 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 3327 orntNew[0] = -2; 3328 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 3329 orntNew[1] = 0; 3330 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3331 orntNew[2] = 0; 3332 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3333 orntNew[3] = -2; 3334 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3335 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3336 #if 1 3337 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3338 for (p = 0; p < 4; ++p) { 3339 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3340 } 3341 #endif 3342 /* F-G face */ 3343 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 3344 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 3345 orntNew[0] = -2; 3346 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 3347 orntNew[1] = 0; 3348 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3349 orntNew[2] = 0; 3350 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3351 orntNew[3] = -2; 3352 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3353 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3354 #if 1 3355 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3356 for (p = 0; p < 4; ++p) { 3357 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3358 } 3359 #endif 3360 /* G-H face */ 3361 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 3362 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 3363 orntNew[0] = -2; 3364 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 3365 orntNew[1] = 0; 3366 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3367 orntNew[2] = 0; 3368 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3369 orntNew[3] = -2; 3370 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3371 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3372 #if 1 3373 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3374 for (p = 0; p < 4; ++p) { 3375 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3376 } 3377 #endif 3378 /* E-H face */ 3379 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 3380 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 3381 orntNew[0] = -2; 3382 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 3383 orntNew[1] = 0; 3384 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3385 orntNew[2] = 0; 3386 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3387 orntNew[3] = -2; 3388 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3389 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3390 #if 1 3391 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3392 for (p = 0; p < 4; ++p) { 3393 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3394 } 3395 #endif 3396 /* A-E face */ 3397 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 3398 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 3399 orntNew[0] = -2; 3400 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 3401 orntNew[1] = 0; 3402 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3403 orntNew[2] = 0; 3404 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3405 orntNew[3] = -2; 3406 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3407 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3408 #if 1 3409 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3410 for (p = 0; p < 4; ++p) { 3411 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3412 } 3413 #endif 3414 /* D-F face */ 3415 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 3416 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 3417 orntNew[0] = -2; 3418 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 3419 orntNew[1] = 0; 3420 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3421 orntNew[2] = 0; 3422 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3423 orntNew[3] = -2; 3424 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3425 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3426 #if 1 3427 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3428 for (p = 0; p < 4; ++p) { 3429 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3430 } 3431 #endif 3432 /* C-G face */ 3433 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 3434 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 3435 orntNew[0] = -2; 3436 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 3437 orntNew[1] = 0; 3438 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3439 orntNew[2] = 0; 3440 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3441 orntNew[3] = -2; 3442 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3443 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3444 #if 1 3445 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3446 for (p = 0; p < 4; ++p) { 3447 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3448 } 3449 #endif 3450 /* B-H face */ 3451 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 3452 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 3453 orntNew[0] = -2; 3454 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 3455 orntNew[1] = 0; 3456 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3457 orntNew[2] = 0; 3458 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3459 orntNew[3] = -2; 3460 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3461 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3462 #if 1 3463 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3464 for (p = 0; p < 4; ++p) { 3465 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3466 } 3467 #endif 3468 for (r = 0; r < 12; ++r) { 3469 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 3470 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 3471 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 3472 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3473 #if 1 3474 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3475 for (p = 0; p < 2; ++p) { 3476 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 3477 } 3478 #endif 3479 } 3480 } 3481 /* Split edges have 2 vertices and the same faces as the parent */ 3482 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3483 for (e = eStart; e < eEnd; ++e) { 3484 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3485 3486 for (r = 0; r < 2; ++r) { 3487 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3488 const PetscInt *cone, *ornt, *support; 3489 PetscInt coneNew[2], coneSize, c, supportSize, s; 3490 3491 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3492 coneNew[0] = vStartNew + (cone[0] - vStart); 3493 coneNew[1] = vStartNew + (cone[1] - vStart); 3494 coneNew[(r+1)%2] = newv; 3495 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3496 #if 1 3497 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3498 for (p = 0; p < 2; ++p) { 3499 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 3500 } 3501 #endif 3502 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3503 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3504 for (s = 0; s < supportSize; ++s) { 3505 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3506 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3507 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3508 for (c = 0; c < coneSize; ++c) { 3509 if (cone[c] == e) break; 3510 } 3511 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 3512 } 3513 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3514 #if 1 3515 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3516 for (p = 0; p < supportSize; ++p) { 3517 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 3518 } 3519 #endif 3520 } 3521 } 3522 /* Face edges have 2 vertices and 2+cells faces */ 3523 for (f = fStart; f < fEnd; ++f) { 3524 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}; 3525 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 3526 const PetscInt *cone, *coneCell, *orntCell, *support; 3527 PetscInt coneNew[2], coneSize, c, supportSize, s; 3528 3529 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3530 for (r = 0; r < 4; ++r) { 3531 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 3532 3533 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 3534 coneNew[1] = newv; 3535 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3536 #if 1 3537 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3538 for (p = 0; p < 2; ++p) { 3539 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 3540 } 3541 #endif 3542 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3543 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3544 supportRef[0] = fStartNew + (f - fStart)*4 + r; 3545 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 3546 for (s = 0; s < supportSize; ++s) { 3547 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3548 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 3549 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 3550 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 3551 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdge_Static(orntCell[c], r)]; 3552 } 3553 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3554 #if 1 3555 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3556 for (p = 0; p < 2+supportSize; ++p) { 3557 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 3558 } 3559 #endif 3560 } 3561 } 3562 /* Cell edges have 2 vertices and 4 faces */ 3563 for (c = cStart; c < cEnd; ++c) { 3564 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}; 3565 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 3566 const PetscInt *cone; 3567 PetscInt coneNew[2], supportNew[4]; 3568 3569 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3570 for (r = 0; r < 6; ++r) { 3571 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 3572 3573 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 3574 coneNew[1] = newv; 3575 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3576 #if 1 3577 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3578 for (p = 0; p < 2; ++p) { 3579 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 3580 } 3581 #endif 3582 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 3583 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3584 #if 1 3585 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3586 for (p = 0; p < 4; ++p) { 3587 if ((supportNew[p] < fStartNew) || (supportNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportNew[p], fStartNew, fEndNew); 3588 } 3589 #endif 3590 } 3591 } 3592 /* Old vertices have identical supports */ 3593 for (v = vStart; v < vEnd; ++v) { 3594 const PetscInt newp = vStartNew + (v - vStart); 3595 const PetscInt *support, *cone; 3596 PetscInt size, s; 3597 3598 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3599 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3600 for (s = 0; s < size; ++s) { 3601 PetscInt r = 0; 3602 3603 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3604 if (cone[1] == v) r = 1; 3605 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3606 } 3607 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3608 #if 1 3609 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3610 for (p = 0; p < size; ++p) { 3611 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 3612 } 3613 #endif 3614 } 3615 /* Edge vertices have 2 + faces supports */ 3616 for (e = eStart; e < eEnd; ++e) { 3617 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3618 const PetscInt *cone, *support; 3619 PetscInt size, s; 3620 3621 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3622 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3623 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3624 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3625 for (s = 0; s < size; ++s) { 3626 PetscInt r; 3627 3628 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3629 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 3630 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 3631 } 3632 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3633 #if 1 3634 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3635 for (p = 0; p < 2+size; ++p) { 3636 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 3637 } 3638 #endif 3639 } 3640 /* Face vertices have 4 + cells supports */ 3641 for (f = fStart; f < fEnd; ++f) { 3642 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 3643 const PetscInt *cone, *support; 3644 PetscInt size, s; 3645 3646 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3647 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3648 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (e - eStart)*2 + (f - fStart)*4 + r; 3649 for (s = 0; s < size; ++s) { 3650 PetscInt r; 3651 3652 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3653 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 3654 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 3655 } 3656 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3657 #if 1 3658 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3659 for (p = 0; p < 4+size; ++p) { 3660 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 3661 } 3662 #endif 3663 } 3664 /* Cell vertices have 6 supports */ 3665 for (c = cStart; c < cEnd; ++c) { 3666 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 3667 PetscInt supportNew[6]; 3668 3669 for (r = 0; r < 6; ++r) { 3670 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 3671 } 3672 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3673 } 3674 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3675 break; 3676 default: 3677 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 3678 } 3679 PetscFunctionReturn(0); 3680 } 3681 3682 #undef __FUNCT__ 3683 #define __FUNCT__ "CellRefinerSetCoordinates" 3684 PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 3685 { 3686 PetscSection coordSection, coordSectionNew; 3687 Vec coordinates, coordinatesNew; 3688 PetscScalar *coords, *coordsNew; 3689 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 3690 PetscInt dim, depth, coordSizeNew, cStart, cEnd, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 3691 PetscErrorCode ierr; 3692 3693 PetscFunctionBegin; 3694 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 3695 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3696 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 3697 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 3698 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 3699 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 3700 ierr = DMPlexGetHybridBounds(dm, NULL, &fMax, &eMax, NULL);CHKERRQ(ierr); 3701 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);} 3702 ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr); 3703 ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 3704 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 3705 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 3706 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dim);CHKERRQ(ierr); 3707 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 3708 if (fMax < 0) fMax = fEnd; 3709 if (eMax < 0) eMax = eEnd; 3710 /* All vertices have the dim coordinates */ 3711 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 3712 ierr = PetscSectionSetDof(coordSectionNew, v, dim);CHKERRQ(ierr); 3713 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dim);CHKERRQ(ierr); 3714 } 3715 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 3716 ierr = DMPlexSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr); 3717 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 3718 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 3719 ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr); 3720 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 3721 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 3722 ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr); 3723 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 3724 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 3725 switch (refiner) { 3726 case 0: break; 3727 case 6: /* Hex 3D */ 3728 /* Face vertices have the average of corner coordinates */ 3729 for (f = fStart; f < fEnd; ++f) { 3730 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 3731 PetscInt *cone = NULL; 3732 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 3733 3734 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3735 for (p = 0; p < closureSize*2; p += 2) { 3736 const PetscInt point = cone[p]; 3737 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 3738 } 3739 for (v = 0; v < coneSize; ++v) { 3740 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 3741 } 3742 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3743 for (d = 0; d < dim; ++d) { 3744 coordsNew[offnew+d] = 0.0; 3745 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 3746 coordsNew[offnew+d] /= coneSize; 3747 } 3748 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3749 } 3750 case 2: /* Hex 2D */ 3751 /* Cell vertices have the average of corner coordinates */ 3752 for (c = cStart; c < cEnd; ++c) { 3753 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (c - cStart) + (dim > 2 ? (fEnd - fStart) : 0); 3754 PetscInt *cone = NULL; 3755 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 3756 3757 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3758 for (p = 0; p < closureSize*2; p += 2) { 3759 const PetscInt point = cone[p]; 3760 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 3761 } 3762 for (v = 0; v < coneSize; ++v) { 3763 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 3764 } 3765 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3766 for (d = 0; d < dim; ++d) { 3767 coordsNew[offnew+d] = 0.0; 3768 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 3769 coordsNew[offnew+d] /= coneSize; 3770 } 3771 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3772 } 3773 case 1: /* Simplicial 2D */ 3774 case 3: /* Hybrid Simplicial 2D */ 3775 case 5: /* Simplicial 3D */ 3776 case 7: /* Hybrid Simplicial 3D */ 3777 /* Edge vertices have the average of endpoint coordinates */ 3778 for (e = eStart; e < eMax; ++e) { 3779 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3780 const PetscInt *cone; 3781 PetscInt coneSize, offA, offB, offnew, d; 3782 3783 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 3784 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 3785 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3786 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 3787 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 3788 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3789 for (d = 0; d < dim; ++d) { 3790 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]); 3791 } 3792 } 3793 /* Old vertices have the same coordinates */ 3794 for (v = vStart; v < vEnd; ++v) { 3795 const PetscInt newv = vStartNew + (v - vStart); 3796 PetscInt off, offnew, d; 3797 3798 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 3799 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3800 for (d = 0; d < dim; ++d) { 3801 coordsNew[offnew+d] = coords[off+d]; 3802 } 3803 } 3804 break; 3805 default: 3806 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 3807 } 3808 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 3809 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 3810 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 3811 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 3812 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 3813 PetscFunctionReturn(0); 3814 } 3815 3816 #undef __FUNCT__ 3817 #define __FUNCT__ "DMPlexCreateProcessSF" 3818 PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 3819 { 3820 PetscInt numRoots, numLeaves, l; 3821 const PetscInt *localPoints; 3822 const PetscSFNode *remotePoints; 3823 PetscInt *localPointsNew; 3824 PetscSFNode *remotePointsNew; 3825 PetscInt *ranks, *ranksNew; 3826 PetscErrorCode ierr; 3827 3828 PetscFunctionBegin; 3829 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 3830 ierr = PetscMalloc(numLeaves * sizeof(PetscInt), &ranks);CHKERRQ(ierr); 3831 for (l = 0; l < numLeaves; ++l) { 3832 ranks[l] = remotePoints[l].rank; 3833 } 3834 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 3835 ierr = PetscMalloc(numLeaves * sizeof(PetscInt), &ranksNew);CHKERRQ(ierr); 3836 ierr = PetscMalloc(numLeaves * sizeof(PetscInt), &localPointsNew);CHKERRQ(ierr); 3837 ierr = PetscMalloc(numLeaves * sizeof(PetscSFNode), &remotePointsNew);CHKERRQ(ierr); 3838 for (l = 0; l < numLeaves; ++l) { 3839 ranksNew[l] = ranks[l]; 3840 localPointsNew[l] = l; 3841 remotePointsNew[l].index = 0; 3842 remotePointsNew[l].rank = ranksNew[l]; 3843 } 3844 ierr = PetscFree(ranks);CHKERRQ(ierr); 3845 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr); 3846 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 3847 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 3848 ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 3849 PetscFunctionReturn(0); 3850 } 3851 3852 #undef __FUNCT__ 3853 #define __FUNCT__ "CellRefinerCreateSF" 3854 PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 3855 { 3856 PetscSF sf, sfNew, sfProcess; 3857 IS processRanks; 3858 MPI_Datatype depthType; 3859 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 3860 const PetscInt *localPoints, *neighbors; 3861 const PetscSFNode *remotePoints; 3862 PetscInt *localPointsNew; 3863 PetscSFNode *remotePointsNew; 3864 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 3865 PetscInt depth, numNeighbors, pStartNew, pEndNew, cStart, cStartNew, cEnd, cMax, vStart, vStartNew, vEnd, vMax, fStart, fStartNew, fEnd, fMax, eStart, eStartNew, eEnd, eMax, r, n; 3866 PetscErrorCode ierr; 3867 3868 PetscFunctionBegin; 3869 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 3870 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3871 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 3872 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 3873 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 3874 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 3875 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 3876 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 3877 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 3878 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 3879 /* Caculate size of new SF */ 3880 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 3881 if (numRoots < 0) PetscFunctionReturn(0); 3882 for (l = 0; l < numLeaves; ++l) { 3883 const PetscInt p = localPoints[l]; 3884 3885 switch (refiner) { 3886 case 1: 3887 /* Simplicial 2D */ 3888 if ((p >= vStart) && (p < vEnd)) { 3889 /* Old vertices stay the same */ 3890 ++numLeavesNew; 3891 } else if ((p >= fStart) && (p < fEnd)) { 3892 /* Old faces add new faces and vertex */ 3893 numLeavesNew += 2 + 1; 3894 } else if ((p >= cStart) && (p < cEnd)) { 3895 /* Old cells add new cells and interior faces */ 3896 numLeavesNew += 4 + 3; 3897 } 3898 break; 3899 case 2: 3900 /* Hex 2D */ 3901 if ((p >= vStart) && (p < vEnd)) { 3902 /* Old vertices stay the same */ 3903 ++numLeavesNew; 3904 } else if ((p >= fStart) && (p < fEnd)) { 3905 /* Old faces add new faces and vertex */ 3906 numLeavesNew += 2 + 1; 3907 } else if ((p >= cStart) && (p < cEnd)) { 3908 /* Old cells add new cells, interior faces, and vertex */ 3909 numLeavesNew += 4 + 4 + 1; 3910 } 3911 break; 3912 case 5: 3913 /* Simplicial 3D */ 3914 if ((p >= vStart) && (p < vEnd)) { 3915 /* Old vertices stay the same */ 3916 ++numLeavesNew; 3917 } else if ((p >= eStart) && (p < eEnd)) { 3918 /* Old edges add new edges and vertex */ 3919 numLeavesNew += 2 + 1; 3920 } else if ((p >= fStart) && (p < fEnd)) { 3921 /* Old faces add new faces and face edges */ 3922 numLeavesNew += 4 + 3; 3923 } else if ((p >= cStart) && (p < cEnd)) { 3924 /* Old cells add new cells and interior faces and edges */ 3925 numLeavesNew += 8 + 8 + 1; 3926 } 3927 break; 3928 case 7: 3929 /* Hybrid Simplicial 3D */ 3930 if ((p >= vStart) && (p < vEnd)) { 3931 /* Interior vertices stay the same */ 3932 ++numLeavesNew; 3933 } else if ((p >= eStart) && (p < eMax)) { 3934 /* Interior edges add new edges and vertex */ 3935 numLeavesNew += 2 + 1; 3936 } else if ((p >= eMax) && (p < eEnd)) { 3937 /* Hybrid edges stay the same */ 3938 ++numLeavesNew; 3939 } else if ((p >= fStart) && (p < fMax)) { 3940 /* Interior faces add new faces and edges */ 3941 numLeavesNew += 4 + 3; 3942 } else if ((p >= fMax) && (p < fEnd)) { 3943 /* Hybrid faces add new faces and edges */ 3944 numLeavesNew += 2 + 1; 3945 } else if ((p >= cStart) && (p < cMax)) { 3946 /* Interior cells add new cells, faces, and edges */ 3947 numLeavesNew += 8 + 8 + 1; 3948 } else if ((p >= cMax) && (p < cEnd)) { 3949 /* Hybrid cells add new cells and faces */ 3950 numLeavesNew += 4 + 3; 3951 } 3952 break; 3953 case 6: 3954 /* Hex 3D */ 3955 if ((p >= vStart) && (p < vEnd)) { 3956 /* Old vertices stay the same */ 3957 ++numLeavesNew; 3958 } else if ((p >= eStart) && (p < eEnd)) { 3959 /* Old edges add new edges, and vertex */ 3960 numLeavesNew += 2 + 1; 3961 } else if ((p >= fStart) && (p < fEnd)) { 3962 /* Old faces add new faces, edges, and vertex */ 3963 numLeavesNew += 4 + 4 + 1; 3964 } else if ((p >= cStart) && (p < cEnd)) { 3965 /* Old cells add new cells, faces, edges, and vertex */ 3966 numLeavesNew += 8 + 12 + 6 + 1; 3967 } 3968 break; 3969 default: 3970 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 3971 } 3972 } 3973 /* Communicate depthSizes for each remote rank */ 3974 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 3975 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 3976 ierr = PetscMalloc5((depth+1)*numNeighbors,PetscInt,&rdepthSize,numNeighbors,PetscInt,&rvStartNew,numNeighbors,PetscInt,&reStartNew,numNeighbors,PetscInt,&rfStartNew,numNeighbors,PetscInt,&rcStartNew);CHKERRQ(ierr); 3977 ierr = PetscMalloc7(depth+1,PetscInt,&depthSizeOld,(depth+1)*numNeighbors,PetscInt,&rdepthSizeOld,(depth+1)*numNeighbors,PetscInt,&rdepthMaxOld,numNeighbors,PetscInt,&rvStart,numNeighbors,PetscInt,&reStart,numNeighbors,PetscInt,&rfStart,numNeighbors,PetscInt,&rcStart);CHKERRQ(ierr); 3978 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 3979 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 3980 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 3981 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 3982 for (n = 0; n < numNeighbors; ++n) { 3983 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 3984 } 3985 depthSizeOld[depth] = cMax; 3986 depthSizeOld[0] = vMax; 3987 depthSizeOld[depth-1] = fMax; 3988 depthSizeOld[1] = eMax; 3989 3990 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 3991 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 3992 3993 depthSizeOld[depth] = cEnd - cStart; 3994 depthSizeOld[0] = vEnd - vStart; 3995 depthSizeOld[depth-1] = fEnd - fStart; 3996 depthSizeOld[1] = eEnd - eStart; 3997 3998 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 3999 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 4000 for (n = 0; n < numNeighbors; ++n) { 4001 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 4002 } 4003 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 4004 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 4005 /* Calculate new point SF */ 4006 ierr = PetscMalloc(numLeavesNew * sizeof(PetscInt), &localPointsNew);CHKERRQ(ierr); 4007 ierr = PetscMalloc(numLeavesNew * sizeof(PetscSFNode), &remotePointsNew);CHKERRQ(ierr); 4008 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 4009 for (l = 0, m = 0; l < numLeaves; ++l) { 4010 PetscInt p = localPoints[l]; 4011 PetscInt rp = remotePoints[l].index, n; 4012 PetscMPIInt rrank = remotePoints[l].rank; 4013 4014 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 4015 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 4016 switch (refiner) { 4017 case 1: 4018 /* Simplicial 2D */ 4019 if ((p >= vStart) && (p < vEnd)) { 4020 /* Old vertices stay the same */ 4021 localPointsNew[m] = vStartNew + (p - vStart); 4022 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4023 remotePointsNew[m].rank = rrank; 4024 ++m; 4025 } else if ((p >= fStart) && (p < fEnd)) { 4026 /* Old faces add new faces and vertex */ 4027 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 4028 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 4029 remotePointsNew[m].rank = rrank; 4030 ++m; 4031 for (r = 0; r < 2; ++r, ++m) { 4032 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 4033 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 4034 remotePointsNew[m].rank = rrank; 4035 } 4036 } else if ((p >= cStart) && (p < cEnd)) { 4037 /* Old cells add new cells and interior faces */ 4038 for (r = 0; r < 4; ++r, ++m) { 4039 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4040 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4041 remotePointsNew[m].rank = rrank; 4042 } 4043 for (r = 0; r < 3; ++r, ++m) { 4044 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 4045 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 4046 remotePointsNew[m].rank = rrank; 4047 } 4048 } 4049 break; 4050 case 2: 4051 /* Hex 2D */ 4052 if ((p >= vStart) && (p < vEnd)) { 4053 /* Old vertices stay the same */ 4054 localPointsNew[m] = vStartNew + (p - vStart); 4055 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4056 remotePointsNew[m].rank = rrank; 4057 ++m; 4058 } else if ((p >= fStart) && (p < fEnd)) { 4059 /* Old faces add new faces and vertex */ 4060 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 4061 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 4062 remotePointsNew[m].rank = rrank; 4063 ++m; 4064 for (r = 0; r < 2; ++r, ++m) { 4065 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 4066 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 4067 remotePointsNew[m].rank = rrank; 4068 } 4069 } else if ((p >= cStart) && (p < cEnd)) { 4070 /* Old cells add new cells, interior faces, and vertex */ 4071 for (r = 0; r < 4; ++r, ++m) { 4072 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4073 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4074 remotePointsNew[m].rank = rrank; 4075 } 4076 for (r = 0; r < 4; ++r, ++m) { 4077 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 4078 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r; 4079 remotePointsNew[m].rank = rrank; 4080 } 4081 for (r = 0; r < 1; ++r, ++m) { 4082 localPointsNew[m] = vStartNew + (fEnd - fStart) + (p - cStart) + r; 4083 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 4084 remotePointsNew[m].rank = rrank; 4085 } 4086 } 4087 break; 4088 case 3: 4089 /* Hybrid simplicial 2D */ 4090 if ((p >= vStart) && (p < vEnd)) { 4091 /* Old vertices stay the same */ 4092 localPointsNew[m] = vStartNew + (p - vStart); 4093 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4094 remotePointsNew[m].rank = rrank; 4095 ++m; 4096 } else if ((p >= fStart) && (p < fMax)) { 4097 /* Old interior faces add new faces and vertex */ 4098 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 4099 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 4100 remotePointsNew[m].rank = rrank; 4101 ++m; 4102 for (r = 0; r < 2; ++r, ++m) { 4103 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 4104 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 4105 remotePointsNew[m].rank = rrank; 4106 } 4107 } else if ((p >= fMax) && (p < fEnd)) { 4108 /* Old hybrid faces stay the same */ 4109 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 4110 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 4111 remotePointsNew[m].rank = rrank; 4112 ++m; 4113 } else if ((p >= cStart) && (p < cMax)) { 4114 /* Old interior cells add new cells and interior faces */ 4115 for (r = 0; r < 4; ++r, ++m) { 4116 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4117 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4118 remotePointsNew[m].rank = rrank; 4119 } 4120 for (r = 0; r < 3; ++r, ++m) { 4121 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 4122 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 4123 remotePointsNew[m].rank = rrank; 4124 } 4125 } else if ((p >= cStart) && (p < cMax)) { 4126 /* Old hybrid cells add new cells and hybrid face */ 4127 for (r = 0; r < 2; ++r, ++m) { 4128 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4129 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4130 remotePointsNew[m].rank = rrank; 4131 } 4132 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 4133 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]); 4134 remotePointsNew[m].rank = rrank; 4135 ++m; 4136 } 4137 break; 4138 case 5: 4139 /* Simplicial 3D */ 4140 if ((p >= vStart) && (p < vEnd)) { 4141 /* Old vertices stay the same */ 4142 localPointsNew[m] = vStartNew + (p - vStart); 4143 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4144 remotePointsNew[m].rank = rrank; 4145 ++m; 4146 } else if ((p >= eStart) && (p < eEnd)) { 4147 /* Old edges add new edges and vertex */ 4148 for (r = 0; r < 2; ++r, ++m) { 4149 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 4150 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 4151 remotePointsNew[m].rank = rrank; 4152 } 4153 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 4154 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 4155 remotePointsNew[m].rank = rrank; 4156 ++m; 4157 } else if ((p >= fStart) && (p < fEnd)) { 4158 /* Old faces add new faces and face edges */ 4159 for (r = 0; r < 4; ++r, ++m) { 4160 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 4161 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 4162 remotePointsNew[m].rank = rrank; 4163 } 4164 for (r = 0; r < 3; ++r, ++m) { 4165 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 4166 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*3 + r; 4167 remotePointsNew[m].rank = rrank; 4168 } 4169 } else if ((p >= cStart) && (p < cEnd)) { 4170 /* Old cells add new cells and interior faces and edges */ 4171 for (r = 0; r < 8; ++r, ++m) { 4172 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 4173 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 4174 remotePointsNew[m].rank = rrank; 4175 } 4176 for (r = 0; r < 8; ++r, ++m) { 4177 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 4178 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*8 + r; 4179 remotePointsNew[m].rank = rrank; 4180 } 4181 for (r = 0; r < 1; ++r, ++m) { 4182 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 4183 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*1 + r; 4184 remotePointsNew[m].rank = rrank; 4185 } 4186 } 4187 break; 4188 case 7: 4189 /* Hybrid Simplicial 3D */ 4190 if ((p >= vStart) && (p < vEnd)) { 4191 /* Interior vertices stay the same */ 4192 localPointsNew[m] = vStartNew + (p - vStart); 4193 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4194 remotePointsNew[m].rank = rrank; 4195 ++m; 4196 } else if ((p >= eStart) && (p < eMax)) { 4197 /* Interior edges add new edges and vertex */ 4198 for (r = 0; r < 2; ++r, ++m) { 4199 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 4200 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 4201 remotePointsNew[m].rank = rrank; 4202 } 4203 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 4204 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 4205 remotePointsNew[m].rank = rrank; 4206 ++m; 4207 } else if ((p >= eMax) && (p < eEnd)) { 4208 /* Hybrid edges stay the same */ 4209 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 4210 remotePointsNew[m].index = rvStartNew[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]); 4211 remotePointsNew[m].rank = rrank; 4212 ++m; 4213 } else if ((p >= fStart) && (p < fMax)) { 4214 /* Interior faces add new faces and edges */ 4215 for (r = 0; r < 4; ++r, ++m) { 4216 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 4217 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 4218 remotePointsNew[m].rank = rrank; 4219 } 4220 for (r = 0; r < 3; ++r, ++m) { 4221 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 4222 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 4223 remotePointsNew[m].rank = rrank; 4224 } 4225 } else if ((p >= fMax) && (p < fEnd)) { 4226 /* Hybrid faces add new faces and edges */ 4227 for (r = 0; r < 2; ++r, ++m) { 4228 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fStart)*2 + r; 4229 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rfStart[n])*2 + r; 4230 remotePointsNew[m].rank = rrank; 4231 } 4232 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart) + (cMax - cStart) + (fEnd - fMax); 4233 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n]) + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1]); 4234 remotePointsNew[m].rank = rrank; 4235 } else if ((p >= cStart) && (p < cMax)) { 4236 /* Interior cells add new cells, faces, and edges */ 4237 for (r = 0; r < 8; ++r, ++m) { 4238 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 4239 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 4240 remotePointsNew[m].rank = rrank; 4241 } 4242 for (r = 0; r < 8; ++r, ++m) { 4243 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 4244 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 4245 remotePointsNew[m].rank = rrank; 4246 } 4247 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + r; 4248 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 + r; 4249 remotePointsNew[m].rank = rrank; 4250 } else if ((p >= cMax) && (p < cEnd)) { 4251 /* Hybrid cells add new cells and faces */ 4252 for (r = 0; r < 4; ++r, ++m) { 4253 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 4254 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 4255 remotePointsNew[m].rank = rrank; 4256 } 4257 for (r = 0; r < 3; ++r, ++m) { 4258 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*4 + (p - cMax)*3 + r; 4259 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])*4 + (rp - rdepthMaxOld[n*(depth+1)+depth])*3 + r; 4260 remotePointsNew[m].rank = rrank; 4261 } 4262 } 4263 break; 4264 case 6: 4265 /* Hex 3D */ 4266 if ((p >= vStart) && (p < vEnd)) { 4267 /* Old vertices stay the same */ 4268 localPointsNew[m] = vStartNew + (p - vStart); 4269 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4270 remotePointsNew[m].rank = rrank; 4271 ++m; 4272 } else if ((p >= eStart) && (p < eEnd)) { 4273 /* Old edges add new edges and vertex */ 4274 for (r = 0; r < 2; ++r, ++m) { 4275 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 4276 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 4277 remotePointsNew[m].rank = rrank; 4278 } 4279 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 4280 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 4281 remotePointsNew[m].rank = rrank; 4282 ++m; 4283 } else if ((p >= fStart) && (p < fEnd)) { 4284 /* Old faces add new faces, edges, and vertex */ 4285 for (r = 0; r < 4; ++r, ++m) { 4286 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 4287 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 4288 remotePointsNew[m].rank = rrank; 4289 } 4290 for (r = 0; r < 4; ++r, ++m) { 4291 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 4292 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*4 + r; 4293 remotePointsNew[m].rank = rrank; 4294 } 4295 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 4296 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]); 4297 remotePointsNew[m].rank = rrank; 4298 ++m; 4299 } else if ((p >= cStart) && (p < cEnd)) { 4300 /* Old cells add new cells, faces, edges, and vertex */ 4301 for (r = 0; r < 8; ++r, ++m) { 4302 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 4303 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 4304 remotePointsNew[m].rank = rrank; 4305 } 4306 for (r = 0; r < 12; ++r, ++m) { 4307 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 4308 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*12 + r; 4309 remotePointsNew[m].rank = rrank; 4310 } 4311 for (r = 0; r < 6; ++r, ++m) { 4312 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 4313 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*6 + r; 4314 remotePointsNew[m].rank = rrank; 4315 } 4316 for (r = 0; r < 1; ++r, ++m) { 4317 localPointsNew[m] = vStartNew + (eEnd - eStart) + (fEnd - fStart) + (p - cStart) + r; 4318 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 4319 remotePointsNew[m].rank = rrank; 4320 } 4321 } 4322 break; 4323 default: 4324 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 4325 } 4326 } 4327 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 4328 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 4329 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 4330 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 4331 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 4332 PetscFunctionReturn(0); 4333 } 4334 4335 #undef __FUNCT__ 4336 #define __FUNCT__ "CellRefinerCreateLabels" 4337 PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 4338 { 4339 PetscInt numLabels, l; 4340 PetscInt depth, newp, cStart, cStartNew, cEnd, cMax, vStart, vStartNew, vEnd, vMax, fStart, fStartNew, fEnd, fMax, eStart, eStartNew, eEnd, eMax, r; 4341 PetscErrorCode ierr; 4342 4343 PetscFunctionBegin; 4344 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 4345 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 4346 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 4347 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 4348 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 4349 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 4350 ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 4351 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 4352 switch (refiner) { 4353 case 0: break; 4354 case 7: 4355 case 8: 4356 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 4357 case 3: 4358 case 4: 4359 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 4360 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 4361 } 4362 for (l = 0; l < numLabels; ++l) { 4363 DMLabel label, labelNew; 4364 const char *lname; 4365 PetscBool isDepth; 4366 IS valueIS; 4367 const PetscInt *values; 4368 PetscInt numValues, val; 4369 4370 ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr); 4371 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 4372 if (isDepth) continue; 4373 ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr); 4374 ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr); 4375 ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 4376 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 4377 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 4378 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 4379 for (val = 0; val < numValues; ++val) { 4380 IS pointIS; 4381 const PetscInt *points; 4382 PetscInt numPoints, n; 4383 4384 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 4385 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 4386 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 4387 for (n = 0; n < numPoints; ++n) { 4388 const PetscInt p = points[n]; 4389 switch (refiner) { 4390 case 1: 4391 /* Simplicial 2D */ 4392 if ((p >= vStart) && (p < vEnd)) { 4393 /* Old vertices stay the same */ 4394 newp = vStartNew + (p - vStart); 4395 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4396 } else if ((p >= fStart) && (p < fEnd)) { 4397 /* Old faces add new faces and vertex */ 4398 newp = vStartNew + (vEnd - vStart) + (p - fStart); 4399 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4400 for (r = 0; r < 2; ++r) { 4401 newp = fStartNew + (p - fStart)*2 + r; 4402 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4403 } 4404 } else if ((p >= cStart) && (p < cEnd)) { 4405 /* Old cells add new cells and interior faces */ 4406 for (r = 0; r < 4; ++r) { 4407 newp = cStartNew + (p - cStart)*4 + r; 4408 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4409 } 4410 for (r = 0; r < 3; ++r) { 4411 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 4412 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4413 } 4414 } 4415 break; 4416 case 2: 4417 /* Hex 2D */ 4418 if ((p >= vStart) && (p < vEnd)) { 4419 /* Old vertices stay the same */ 4420 newp = vStartNew + (p - vStart); 4421 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4422 } else if ((p >= fStart) && (p < fEnd)) { 4423 /* Old faces add new faces and vertex */ 4424 newp = vStartNew + (vEnd - vStart) + (p - fStart); 4425 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4426 for (r = 0; r < 2; ++r) { 4427 newp = fStartNew + (p - fStart)*2 + r; 4428 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4429 } 4430 } else if ((p >= cStart) && (p < cEnd)) { 4431 /* Old cells add new cells and interior faces and vertex */ 4432 for (r = 0; r < 4; ++r) { 4433 newp = cStartNew + (p - cStart)*4 + r; 4434 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4435 } 4436 for (r = 0; r < 4; ++r) { 4437 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 4438 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4439 } 4440 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 4441 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4442 } 4443 break; 4444 case 3: 4445 /* Hybrid simplicial 2D */ 4446 if ((p >= vStart) && (p < vEnd)) { 4447 /* Old vertices stay the same */ 4448 newp = vStartNew + (p - vStart); 4449 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4450 } else if ((p >= fStart) && (p < fMax)) { 4451 /* Old interior faces add new faces and vertex */ 4452 newp = vStartNew + (vEnd - vStart) + (p - fStart); 4453 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4454 for (r = 0; r < 2; ++r) { 4455 newp = fStartNew + (p - fStart)*2 + r; 4456 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4457 } 4458 } else if ((p >= fMax) && (p < fEnd)) { 4459 /* Old hybrid faces stay the same */ 4460 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 4461 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4462 } else if ((p >= cStart) && (p < cMax)) { 4463 /* Old interior cells add new cells and interior faces */ 4464 for (r = 0; r < 4; ++r) { 4465 newp = cStartNew + (p - cStart)*4 + r; 4466 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4467 } 4468 for (r = 0; r < 3; ++r) { 4469 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 4470 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4471 } 4472 } else if ((p >= cMax) && (p < cEnd)) { 4473 /* Old hybrid cells add new cells and hybrid face */ 4474 for (r = 0; r < 2; ++r) { 4475 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 4476 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4477 } 4478 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 4479 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4480 } 4481 break; 4482 case 5: 4483 /* Simplicial 3D */ 4484 if ((p >= vStart) && (p < vEnd)) { 4485 /* Old vertices stay the same */ 4486 newp = vStartNew + (p - vStart); 4487 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4488 } else if ((p >= eStart) && (p < eEnd)) { 4489 /* Old edges add new edges and vertex */ 4490 for (r = 0; r < 2; ++r) { 4491 newp = eStartNew + (p - eStart)*2 + r; 4492 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4493 } 4494 newp = vStartNew + (vEnd - vStart) + (p - eStart); 4495 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4496 } else if ((p >= fStart) && (p < fEnd)) { 4497 /* Old faces add new faces and edges */ 4498 for (r = 0; r < 4; ++r) { 4499 newp = fStartNew + (p - fStart)*4 + r; 4500 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4501 } 4502 for (r = 0; r < 3; ++r) { 4503 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 4504 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4505 } 4506 } else if ((p >= cStart) && (p < cEnd)) { 4507 /* Old cells add new cells and interior faces and edges */ 4508 for (r = 0; r < 8; ++r) { 4509 newp = cStartNew + (p - cStart)*8 + r; 4510 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4511 } 4512 for (r = 0; r < 8; ++r) { 4513 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 4514 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4515 } 4516 for (r = 0; r < 1; ++r) { 4517 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 4518 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4519 } 4520 } 4521 break; 4522 case 7: 4523 /* Hybrid Simplicial 3D */ 4524 if ((p >= vStart) && (p < vEnd)) { 4525 /* Interior vertices stay the same */ 4526 newp = vStartNew + (p - vStart); 4527 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4528 } else if ((p >= eStart) && (p < eMax)) { 4529 /* Interior edges add new edges and vertex */ 4530 for (r = 0; r < 2; ++r) { 4531 newp = eStartNew + (p - eStart)*2 + r; 4532 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4533 } 4534 newp = vStartNew + (vEnd - vStart) + (p - eStart); 4535 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4536 } else if ((p >= eMax) && (p < eEnd)) { 4537 /* Hybrid edges stay the same */ 4538 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 4539 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4540 } else if ((p >= fStart) && (p < fMax)) { 4541 /* Interior faces add new faces and edges */ 4542 for (r = 0; r < 4; ++r) { 4543 newp = fStartNew + (p - fStart)*4 + r; 4544 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4545 } 4546 for (r = 0; r < 3; ++r) { 4547 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 4548 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4549 } 4550 } else if ((p >= fMax) && (p < fEnd)) { 4551 /* Hybrid faces add new faces and edges */ 4552 for (r = 0; r < 2; ++r) { 4553 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 4554 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4555 } 4556 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 4557 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4558 } else if ((p >= cStart) && (p < cMax)) { 4559 /* Interior cells add new cells, faces, and edges */ 4560 for (r = 0; r < 8; ++r) { 4561 newp = cStartNew + (p - cStart)*8 + r; 4562 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4563 } 4564 for (r = 0; r < 8; ++r) { 4565 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 4566 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4567 } 4568 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 4569 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4570 } else if ((p >= cMax) && (p < cEnd)) { 4571 /* Hybrid cells add new cells and faces */ 4572 for (r = 0; r < 4; ++r) { 4573 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 4574 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4575 } 4576 for (r = 0; r < 3; ++r) { 4577 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 4578 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4579 } 4580 } 4581 break; 4582 case 6: 4583 /* Hex 3D */ 4584 if ((p >= vStart) && (p < vEnd)) { 4585 /* Old vertices stay the same */ 4586 newp = vStartNew + (p - vStart); 4587 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4588 } else if ((p >= eStart) && (p < eEnd)) { 4589 /* Old edges add new edges and vertex */ 4590 for (r = 0; r < 2; ++r) { 4591 newp = eStartNew + (p - eStart)*2 + r; 4592 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4593 } 4594 newp = vStartNew + (vEnd - vStart) + (p - eStart); 4595 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4596 } else if ((p >= fStart) && (p < fEnd)) { 4597 /* Old faces add new faces, edges, and vertex */ 4598 for (r = 0; r < 4; ++r) { 4599 newp = fStartNew + (p - fStart)*4 + r; 4600 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4601 } 4602 for (r = 0; r < 4; ++r) { 4603 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 4604 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4605 } 4606 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 4607 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4608 } else if ((p >= cStart) && (p < cEnd)) { 4609 /* Old cells add new cells, faces, edges, and vertex */ 4610 for (r = 0; r < 8; ++r) { 4611 newp = cStartNew + (p - cStart)*8 + r; 4612 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4613 } 4614 for (r = 0; r < 12; ++r) { 4615 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 4616 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4617 } 4618 for (r = 0; r < 6; ++r) { 4619 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 4620 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4621 } 4622 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 4623 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4624 } 4625 break; 4626 default: 4627 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 4628 } 4629 } 4630 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 4631 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 4632 } 4633 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 4634 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 4635 if (0) { 4636 ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr); 4637 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 4638 ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 4639 } 4640 } 4641 PetscFunctionReturn(0); 4642 } 4643 4644 #undef __FUNCT__ 4645 #define __FUNCT__ "DMPlexRefineUniform_Internal" 4646 /* This will only work for interpolated meshes */ 4647 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 4648 { 4649 DM rdm; 4650 PetscInt *depthSize; 4651 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 4652 PetscErrorCode ierr; 4653 4654 PetscFunctionBegin; 4655 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 4656 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 4657 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 4658 ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr); 4659 /* Calculate number of new points of each depth */ 4660 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 4661 ierr = PetscMalloc((depth+1) * sizeof(PetscInt), &depthSize);CHKERRQ(ierr); 4662 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 4663 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 4664 /* Step 1: Set chart */ 4665 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 4666 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 4667 /* Step 2: Set cone/support sizes */ 4668 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4669 /* Step 3: Setup refined DM */ 4670 ierr = DMSetUp(rdm);CHKERRQ(ierr); 4671 /* Step 4: Set cones and supports */ 4672 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4673 /* Step 5: Stratify */ 4674 ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 4675 /* Step 6: Set coordinates for vertices */ 4676 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4677 /* Step 7: Create pointSF */ 4678 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4679 /* Step 8: Create labels */ 4680 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4681 ierr = PetscFree(depthSize);CHKERRQ(ierr); 4682 4683 *dmRefined = rdm; 4684 PetscFunctionReturn(0); 4685 } 4686 4687 #undef __FUNCT__ 4688 #define __FUNCT__ "DMPlexSetRefinementUniform" 4689 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 4690 { 4691 DM_Plex *mesh = (DM_Plex*) dm->data; 4692 4693 PetscFunctionBegin; 4694 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4695 mesh->refinementUniform = refinementUniform; 4696 PetscFunctionReturn(0); 4697 } 4698 4699 #undef __FUNCT__ 4700 #define __FUNCT__ "DMPlexGetRefinementUniform" 4701 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 4702 { 4703 DM_Plex *mesh = (DM_Plex*) dm->data; 4704 4705 PetscFunctionBegin; 4706 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4707 PetscValidPointer(refinementUniform, 2); 4708 *refinementUniform = mesh->refinementUniform; 4709 PetscFunctionReturn(0); 4710 } 4711 4712 #undef __FUNCT__ 4713 #define __FUNCT__ "DMPlexSetRefinementLimit" 4714 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 4715 { 4716 DM_Plex *mesh = (DM_Plex*) dm->data; 4717 4718 PetscFunctionBegin; 4719 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4720 mesh->refinementLimit = refinementLimit; 4721 PetscFunctionReturn(0); 4722 } 4723 4724 #undef __FUNCT__ 4725 #define __FUNCT__ "DMPlexGetRefinementLimit" 4726 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 4727 { 4728 DM_Plex *mesh = (DM_Plex*) dm->data; 4729 4730 PetscFunctionBegin; 4731 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4732 PetscValidPointer(refinementLimit, 2); 4733 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 4734 *refinementLimit = mesh->refinementLimit; 4735 PetscFunctionReturn(0); 4736 } 4737 4738 #undef __FUNCT__ 4739 #define __FUNCT__ "DMPlexGetCellRefiner_Internal" 4740 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 4741 { 4742 PetscInt dim, cStart, cEnd, coneSize, cMax; 4743 PetscErrorCode ierr; 4744 4745 PetscFunctionBegin; 4746 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 4747 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 4748 if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);} 4749 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 4750 ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 4751 switch (dim) { 4752 case 2: 4753 switch (coneSize) { 4754 case 3: 4755 if (cMax >= 0) *cellRefiner = 3; /* Hybrid */ 4756 else *cellRefiner = 1; /* Triangular */ 4757 break; 4758 case 4: 4759 if (cMax >= 0) *cellRefiner = 4; /* Hybrid */ 4760 else *cellRefiner = 2; /* Quadrilateral */ 4761 break; 4762 default: 4763 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 4764 } 4765 break; 4766 case 3: 4767 switch (coneSize) { 4768 case 4: 4769 if (cMax >= 0) *cellRefiner = 7; /* Hybrid */ 4770 else *cellRefiner = 5; /* Tetrahedral */ 4771 break; 4772 case 6: 4773 if (cMax >= 0) *cellRefiner = 8; /* Hybrid */ 4774 else *cellRefiner = 6; /* hexahedral */ 4775 break; 4776 default: 4777 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 4778 } 4779 break; 4780 default: 4781 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 4782 } 4783 PetscFunctionReturn(0); 4784 } 4785