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 + (GetTriSubfaceInverse_Static(ornt[c], 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, *cornt; 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 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 2912 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 2913 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]); 2914 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + GetTriSubfaceInverse_Static(cornt[0], c-2); 2915 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (GetTriSubfaceInverse_Static(cornt[0], c-2) + 1)%3; 2916 } 2917 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2918 #if 1 2919 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 2920 for (p = 0; p < 2+size*2; ++p) { 2921 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); 2922 } 2923 #endif 2924 } 2925 /* Interior vertices have identical supports */ 2926 for (v = vStart; v < vEnd; ++v) { 2927 const PetscInt newp = vStartNew + (v - vStart); 2928 const PetscInt *support, *cone; 2929 PetscInt size, s; 2930 2931 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2932 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2933 for (s = 0; s < size; ++s) { 2934 PetscInt r = 0; 2935 2936 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2937 if (cone[1] == v) r = 1; 2938 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 2939 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 2940 } 2941 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2942 #if 1 2943 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2944 for (p = 0; p < size; ++p) { 2945 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); 2946 } 2947 #endif 2948 } 2949 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 2950 for (e = eStart; e < eMax; ++e) { 2951 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 2952 const PetscInt *cone, *support; 2953 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 2954 2955 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 2956 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2957 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 2958 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 2959 for (s = 0; s < size; ++s) { 2960 PetscInt r = 0; 2961 2962 if (support[s] < fMax) { 2963 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2964 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2965 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 2966 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 2967 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 2968 faceSize += 2; 2969 } else { 2970 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 2971 ++faceSize; 2972 } 2973 } 2974 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2975 for (s = 0; s < starSize*2; s += 2) { 2976 const PetscInt *cone, *ornt; 2977 PetscInt e01, e23; 2978 2979 if ((star[s] >= cStart) && (star[s] < cMax)) { 2980 /* Check edge 0-1 */ 2981 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2982 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2983 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 2984 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 2985 /* Check edge 2-3 */ 2986 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2987 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2988 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 2989 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 2990 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 2991 } 2992 } 2993 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2994 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2995 #if 1 2996 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2997 for (p = 0; p < 2+faceSize+cellSize; ++p) { 2998 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); 2999 } 3000 #endif 3001 } 3002 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3003 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 3004 break; 3005 case 6: 3006 /* Hex 3D */ 3007 /* 3008 Bottom (viewed from top) Top 3009 1---------2---------2 7---------2---------6 3010 | | | | | | 3011 | B 2 C | | H 2 G | 3012 | | | | | | 3013 3----3----0----1----1 3----3----0----1----1 3014 | | | | | | 3015 | A 0 D | | E 0 F | 3016 | | | | | | 3017 0---------0---------3 4---------0---------5 3018 */ 3019 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 3020 for (c = cStart; c < cEnd; ++c) { 3021 const PetscInt newp = (c - cStart)*8; 3022 const PetscInt *cone, *ornt; 3023 PetscInt coneNew[6], orntNew[6]; 3024 3025 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3026 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3027 /* A hex */ 3028 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 3029 orntNew[0] = ornt[0]; 3030 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3031 orntNew[1] = 0; 3032 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 3033 orntNew[2] = ornt[2]; 3034 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3035 orntNew[3] = 0; 3036 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3037 orntNew[4] = 0; 3038 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 3039 orntNew[5] = ornt[5]; 3040 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3041 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3042 #if 1 3043 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); 3044 for (p = 0; p < 6; ++p) { 3045 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); 3046 } 3047 #endif 3048 /* B hex */ 3049 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 3050 orntNew[0] = ornt[0]; 3051 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3052 orntNew[1] = 0; 3053 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3054 orntNew[2] = -3; 3055 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 3056 orntNew[3] = ornt[3]; 3057 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3058 orntNew[4] = 0; 3059 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 3060 orntNew[5] = ornt[5]; 3061 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3062 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3063 #if 1 3064 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); 3065 for (p = 0; p < 6; ++p) { 3066 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); 3067 } 3068 #endif 3069 /* C hex */ 3070 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 3071 orntNew[0] = ornt[0]; 3072 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3073 orntNew[1] = 0; 3074 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3075 orntNew[2] = 0; 3076 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 3077 orntNew[3] = ornt[3]; 3078 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 3079 orntNew[4] = ornt[4]; 3080 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3081 orntNew[5] = -3; 3082 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3083 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3084 #if 1 3085 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); 3086 for (p = 0; p < 6; ++p) { 3087 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); 3088 } 3089 #endif 3090 /* D hex */ 3091 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 3092 orntNew[0] = ornt[0]; 3093 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3094 orntNew[1] = 0; 3095 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 3096 orntNew[2] = ornt[2]; 3097 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3098 orntNew[3] = -3; 3099 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 3100 orntNew[4] = ornt[4]; 3101 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3102 orntNew[5] = -3; 3103 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3104 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3105 #if 1 3106 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); 3107 for (p = 0; p < 6; ++p) { 3108 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); 3109 } 3110 #endif 3111 /* E hex */ 3112 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3113 orntNew[0] = -3; 3114 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 3115 orntNew[1] = ornt[1]; 3116 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 3117 orntNew[2] = ornt[2]; 3118 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3119 orntNew[3] = 0; 3120 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3121 orntNew[4] = 0; 3122 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 3123 orntNew[5] = ornt[5]; 3124 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3125 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3126 #if 1 3127 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); 3128 for (p = 0; p < 6; ++p) { 3129 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); 3130 } 3131 #endif 3132 /* F hex */ 3133 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3134 orntNew[0] = -3; 3135 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 3136 orntNew[1] = ornt[1]; 3137 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 3138 orntNew[2] = ornt[2]; 3139 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3140 orntNew[3] = 0; 3141 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 3142 orntNew[4] = ornt[4]; 3143 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3144 orntNew[5] = -3; 3145 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3146 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3147 #if 1 3148 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); 3149 for (p = 0; p < 6; ++p) { 3150 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); 3151 } 3152 #endif 3153 /* G hex */ 3154 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3155 orntNew[0] = -3; 3156 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 3157 orntNew[1] = ornt[1]; 3158 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3159 orntNew[2] = -3; 3160 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 3161 orntNew[3] = ornt[3]; 3162 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 3163 orntNew[4] = ornt[4]; 3164 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3165 orntNew[5] = 0; 3166 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3167 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3168 #if 1 3169 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); 3170 for (p = 0; p < 6; ++p) { 3171 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); 3172 } 3173 #endif 3174 /* H hex */ 3175 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3176 orntNew[0] = -3; 3177 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 3178 orntNew[1] = ornt[1]; 3179 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3180 orntNew[2] = -3; 3181 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 3182 orntNew[3] = ornt[3]; 3183 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3184 orntNew[4] = -3; 3185 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 3186 orntNew[5] = ornt[5]; 3187 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3188 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3189 #if 1 3190 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); 3191 for (p = 0; p < 6; ++p) { 3192 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); 3193 } 3194 #endif 3195 } 3196 /* Split faces have 4 edges and the same cells as the parent */ 3197 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3198 ierr = PetscMalloc((4 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr); 3199 for (f = fStart; f < fEnd; ++f) { 3200 for (r = 0; r < 4; ++r) { 3201 /* TODO: This can come from GetFaces_Internal() */ 3202 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}; 3203 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 3204 const PetscInt *cone, *ornt, *support; 3205 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 3206 3207 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3208 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3209 coneNew[0] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 3210 orntNew[0] = ornt[(r+3)%4]; 3211 coneNew[1] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 3212 orntNew[1] = ornt[r]; 3213 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 3214 orntNew[2] = 0; 3215 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 3216 orntNew[3] = -2; 3217 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3218 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3219 #if 1 3220 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3221 for (p = 0; p < 4; ++p) { 3222 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); 3223 } 3224 #endif 3225 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3226 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3227 for (s = 0; s < supportSize; ++s) { 3228 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3229 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3230 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3231 for (c = 0; c < coneSize; ++c) { 3232 if (cone[c] == f) break; 3233 } 3234 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubface_Static(ornt[c], r)]; 3235 } 3236 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3237 #if 1 3238 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3239 for (p = 0; p < supportSize; ++p) { 3240 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); 3241 } 3242 #endif 3243 } 3244 } 3245 /* Interior faces have 4 edges and 2 cells */ 3246 for (c = cStart; c < cEnd; ++c) { 3247 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}; 3248 const PetscInt *cone, *ornt; 3249 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 3250 3251 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3252 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3253 /* A-D face */ 3254 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 3255 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 3256 orntNew[0] = -2; 3257 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 3258 orntNew[1] = 0; 3259 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3260 orntNew[2] = 0; 3261 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3262 orntNew[3] = -2; 3263 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3264 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3265 #if 1 3266 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3267 for (p = 0; p < 4; ++p) { 3268 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); 3269 } 3270 #endif 3271 /* C-D face */ 3272 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 3273 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 3274 orntNew[0] = -2; 3275 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 3276 orntNew[1] = 0; 3277 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3278 orntNew[2] = 0; 3279 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3280 orntNew[3] = -2; 3281 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3282 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3283 #if 1 3284 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3285 for (p = 0; p < 4; ++p) { 3286 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); 3287 } 3288 #endif 3289 /* B-C face */ 3290 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 3291 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 3292 orntNew[0] = -2; 3293 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 3294 orntNew[1] = 0; 3295 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3296 orntNew[2] = 0; 3297 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3298 orntNew[3] = -2; 3299 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3300 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3301 #if 1 3302 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3303 for (p = 0; p < 4; ++p) { 3304 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); 3305 } 3306 #endif 3307 /* A-B face */ 3308 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 3309 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 3310 orntNew[0] = -2; 3311 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 3312 orntNew[1] = 0; 3313 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3314 orntNew[2] = 0; 3315 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3316 orntNew[3] = -2; 3317 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3318 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3319 #if 1 3320 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3321 for (p = 0; p < 4; ++p) { 3322 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); 3323 } 3324 #endif 3325 /* E-F face */ 3326 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 3327 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 3328 orntNew[0] = -2; 3329 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 3330 orntNew[1] = 0; 3331 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3332 orntNew[2] = 0; 3333 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3334 orntNew[3] = -2; 3335 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3336 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3337 #if 1 3338 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3339 for (p = 0; p < 4; ++p) { 3340 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); 3341 } 3342 #endif 3343 /* F-G face */ 3344 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 3345 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 3346 orntNew[0] = -2; 3347 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 3348 orntNew[1] = 0; 3349 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3350 orntNew[2] = 0; 3351 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3352 orntNew[3] = -2; 3353 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3354 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3355 #if 1 3356 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3357 for (p = 0; p < 4; ++p) { 3358 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); 3359 } 3360 #endif 3361 /* G-H face */ 3362 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 3363 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 3364 orntNew[0] = -2; 3365 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 3366 orntNew[1] = 0; 3367 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3368 orntNew[2] = 0; 3369 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3370 orntNew[3] = -2; 3371 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3372 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3373 #if 1 3374 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3375 for (p = 0; p < 4; ++p) { 3376 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); 3377 } 3378 #endif 3379 /* E-H face */ 3380 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 3381 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 3382 orntNew[0] = -2; 3383 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 3384 orntNew[1] = 0; 3385 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3386 orntNew[2] = 0; 3387 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3388 orntNew[3] = -2; 3389 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3390 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3391 #if 1 3392 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3393 for (p = 0; p < 4; ++p) { 3394 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); 3395 } 3396 #endif 3397 /* A-E face */ 3398 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 3399 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 3400 orntNew[0] = -2; 3401 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 3402 orntNew[1] = 0; 3403 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3404 orntNew[2] = 0; 3405 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3406 orntNew[3] = -2; 3407 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3408 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3409 #if 1 3410 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3411 for (p = 0; p < 4; ++p) { 3412 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); 3413 } 3414 #endif 3415 /* D-F face */ 3416 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 3417 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 3418 orntNew[0] = -2; 3419 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 3420 orntNew[1] = 0; 3421 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3422 orntNew[2] = 0; 3423 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3424 orntNew[3] = -2; 3425 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3426 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3427 #if 1 3428 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3429 for (p = 0; p < 4; ++p) { 3430 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); 3431 } 3432 #endif 3433 /* C-G face */ 3434 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 3435 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 3436 orntNew[0] = -2; 3437 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 3438 orntNew[1] = 0; 3439 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3440 orntNew[2] = 0; 3441 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3442 orntNew[3] = -2; 3443 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3444 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3445 #if 1 3446 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3447 for (p = 0; p < 4; ++p) { 3448 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); 3449 } 3450 #endif 3451 /* B-H face */ 3452 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 3453 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 3454 orntNew[0] = -2; 3455 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 3456 orntNew[1] = 0; 3457 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3458 orntNew[2] = 0; 3459 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3460 orntNew[3] = -2; 3461 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3462 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3463 #if 1 3464 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3465 for (p = 0; p < 4; ++p) { 3466 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); 3467 } 3468 #endif 3469 for (r = 0; r < 12; ++r) { 3470 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 3471 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 3472 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 3473 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3474 #if 1 3475 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3476 for (p = 0; p < 2; ++p) { 3477 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); 3478 } 3479 #endif 3480 } 3481 } 3482 /* Split edges have 2 vertices and the same faces as the parent */ 3483 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3484 for (e = eStart; e < eEnd; ++e) { 3485 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3486 3487 for (r = 0; r < 2; ++r) { 3488 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3489 const PetscInt *cone, *ornt, *support; 3490 PetscInt coneNew[2], coneSize, c, supportSize, s; 3491 3492 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3493 coneNew[0] = vStartNew + (cone[0] - vStart); 3494 coneNew[1] = vStartNew + (cone[1] - vStart); 3495 coneNew[(r+1)%2] = newv; 3496 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3497 #if 1 3498 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3499 for (p = 0; p < 2; ++p) { 3500 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); 3501 } 3502 #endif 3503 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3504 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3505 for (s = 0; s < supportSize; ++s) { 3506 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3507 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3508 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3509 for (c = 0; c < coneSize; ++c) { 3510 if (cone[c] == e) break; 3511 } 3512 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 3513 } 3514 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3515 #if 1 3516 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3517 for (p = 0; p < supportSize; ++p) { 3518 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); 3519 } 3520 #endif 3521 } 3522 } 3523 /* Face edges have 2 vertices and 2+cells faces */ 3524 for (f = fStart; f < fEnd; ++f) { 3525 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}; 3526 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 3527 const PetscInt *cone, *coneCell, *orntCell, *support; 3528 PetscInt coneNew[2], coneSize, c, supportSize, s; 3529 3530 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3531 for (r = 0; r < 4; ++r) { 3532 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 3533 3534 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 3535 coneNew[1] = newv; 3536 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3537 #if 1 3538 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3539 for (p = 0; p < 2; ++p) { 3540 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); 3541 } 3542 #endif 3543 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3544 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3545 supportRef[0] = fStartNew + (f - fStart)*4 + r; 3546 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 3547 for (s = 0; s < supportSize; ++s) { 3548 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3549 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 3550 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 3551 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 3552 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdge_Static(orntCell[c], r)]; 3553 } 3554 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3555 #if 1 3556 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3557 for (p = 0; p < 2+supportSize; ++p) { 3558 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); 3559 } 3560 #endif 3561 } 3562 } 3563 /* Cell edges have 2 vertices and 4 faces */ 3564 for (c = cStart; c < cEnd; ++c) { 3565 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}; 3566 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 3567 const PetscInt *cone; 3568 PetscInt coneNew[2], supportNew[4]; 3569 3570 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3571 for (r = 0; r < 6; ++r) { 3572 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 3573 3574 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 3575 coneNew[1] = newv; 3576 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3577 #if 1 3578 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3579 for (p = 0; p < 2; ++p) { 3580 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); 3581 } 3582 #endif 3583 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 3584 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3585 #if 1 3586 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3587 for (p = 0; p < 4; ++p) { 3588 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); 3589 } 3590 #endif 3591 } 3592 } 3593 /* Old vertices have identical supports */ 3594 for (v = vStart; v < vEnd; ++v) { 3595 const PetscInt newp = vStartNew + (v - vStart); 3596 const PetscInt *support, *cone; 3597 PetscInt size, s; 3598 3599 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3600 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3601 for (s = 0; s < size; ++s) { 3602 PetscInt r = 0; 3603 3604 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3605 if (cone[1] == v) r = 1; 3606 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3607 } 3608 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3609 #if 1 3610 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3611 for (p = 0; p < size; ++p) { 3612 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); 3613 } 3614 #endif 3615 } 3616 /* Edge vertices have 2 + faces supports */ 3617 for (e = eStart; e < eEnd; ++e) { 3618 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3619 const PetscInt *cone, *support; 3620 PetscInt size, s; 3621 3622 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3623 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3624 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3625 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3626 for (s = 0; s < size; ++s) { 3627 PetscInt r; 3628 3629 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3630 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 3631 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 3632 } 3633 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3634 #if 1 3635 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3636 for (p = 0; p < 2+size; ++p) { 3637 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); 3638 } 3639 #endif 3640 } 3641 /* Face vertices have 4 + cells supports */ 3642 for (f = fStart; f < fEnd; ++f) { 3643 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 3644 const PetscInt *cone, *support; 3645 PetscInt size, s; 3646 3647 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3648 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3649 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (e - eStart)*2 + (f - fStart)*4 + r; 3650 for (s = 0; s < size; ++s) { 3651 PetscInt r; 3652 3653 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3654 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 3655 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 3656 } 3657 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3658 #if 1 3659 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3660 for (p = 0; p < 4+size; ++p) { 3661 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); 3662 } 3663 #endif 3664 } 3665 /* Cell vertices have 6 supports */ 3666 for (c = cStart; c < cEnd; ++c) { 3667 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 3668 PetscInt supportNew[6]; 3669 3670 for (r = 0; r < 6; ++r) { 3671 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 3672 } 3673 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3674 } 3675 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3676 break; 3677 default: 3678 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 3679 } 3680 PetscFunctionReturn(0); 3681 } 3682 3683 #undef __FUNCT__ 3684 #define __FUNCT__ "CellRefinerSetCoordinates" 3685 PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 3686 { 3687 PetscSection coordSection, coordSectionNew; 3688 Vec coordinates, coordinatesNew; 3689 PetscScalar *coords, *coordsNew; 3690 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 3691 PetscInt dim, depth, coordSizeNew, cStart, cEnd, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 3692 PetscErrorCode ierr; 3693 3694 PetscFunctionBegin; 3695 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 3696 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3697 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 3698 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 3699 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 3700 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 3701 ierr = DMPlexGetHybridBounds(dm, NULL, &fMax, &eMax, NULL);CHKERRQ(ierr); 3702 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);} 3703 ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr); 3704 ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 3705 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 3706 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 3707 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dim);CHKERRQ(ierr); 3708 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 3709 if (fMax < 0) fMax = fEnd; 3710 if (eMax < 0) eMax = eEnd; 3711 /* All vertices have the dim coordinates */ 3712 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 3713 ierr = PetscSectionSetDof(coordSectionNew, v, dim);CHKERRQ(ierr); 3714 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dim);CHKERRQ(ierr); 3715 } 3716 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 3717 ierr = DMPlexSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr); 3718 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 3719 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 3720 ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr); 3721 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 3722 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 3723 ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr); 3724 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 3725 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 3726 switch (refiner) { 3727 case 0: break; 3728 case 6: /* Hex 3D */ 3729 /* Face vertices have the average of corner coordinates */ 3730 for (f = fStart; f < fEnd; ++f) { 3731 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 3732 PetscInt *cone = NULL; 3733 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 3734 3735 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3736 for (p = 0; p < closureSize*2; p += 2) { 3737 const PetscInt point = cone[p]; 3738 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 3739 } 3740 for (v = 0; v < coneSize; ++v) { 3741 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 3742 } 3743 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3744 for (d = 0; d < dim; ++d) { 3745 coordsNew[offnew+d] = 0.0; 3746 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 3747 coordsNew[offnew+d] /= coneSize; 3748 } 3749 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3750 } 3751 case 2: /* Hex 2D */ 3752 /* Cell vertices have the average of corner coordinates */ 3753 for (c = cStart; c < cEnd; ++c) { 3754 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (c - cStart) + (dim > 2 ? (fEnd - fStart) : 0); 3755 PetscInt *cone = NULL; 3756 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 3757 3758 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3759 for (p = 0; p < closureSize*2; p += 2) { 3760 const PetscInt point = cone[p]; 3761 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 3762 } 3763 for (v = 0; v < coneSize; ++v) { 3764 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 3765 } 3766 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3767 for (d = 0; d < dim; ++d) { 3768 coordsNew[offnew+d] = 0.0; 3769 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 3770 coordsNew[offnew+d] /= coneSize; 3771 } 3772 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3773 } 3774 case 1: /* Simplicial 2D */ 3775 case 3: /* Hybrid Simplicial 2D */ 3776 case 5: /* Simplicial 3D */ 3777 case 7: /* Hybrid Simplicial 3D */ 3778 /* Edge vertices have the average of endpoint coordinates */ 3779 for (e = eStart; e < eMax; ++e) { 3780 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3781 const PetscInt *cone; 3782 PetscInt coneSize, offA, offB, offnew, d; 3783 3784 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 3785 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 3786 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3787 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 3788 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 3789 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3790 for (d = 0; d < dim; ++d) { 3791 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]); 3792 } 3793 } 3794 /* Old vertices have the same coordinates */ 3795 for (v = vStart; v < vEnd; ++v) { 3796 const PetscInt newv = vStartNew + (v - vStart); 3797 PetscInt off, offnew, d; 3798 3799 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 3800 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3801 for (d = 0; d < dim; ++d) { 3802 coordsNew[offnew+d] = coords[off+d]; 3803 } 3804 } 3805 break; 3806 default: 3807 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 3808 } 3809 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 3810 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 3811 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 3812 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 3813 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 3814 PetscFunctionReturn(0); 3815 } 3816 3817 #undef __FUNCT__ 3818 #define __FUNCT__ "DMPlexCreateProcessSF" 3819 PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 3820 { 3821 PetscInt numRoots, numLeaves, l; 3822 const PetscInt *localPoints; 3823 const PetscSFNode *remotePoints; 3824 PetscInt *localPointsNew; 3825 PetscSFNode *remotePointsNew; 3826 PetscInt *ranks, *ranksNew; 3827 PetscErrorCode ierr; 3828 3829 PetscFunctionBegin; 3830 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 3831 ierr = PetscMalloc(numLeaves * sizeof(PetscInt), &ranks);CHKERRQ(ierr); 3832 for (l = 0; l < numLeaves; ++l) { 3833 ranks[l] = remotePoints[l].rank; 3834 } 3835 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 3836 ierr = PetscMalloc(numLeaves * sizeof(PetscInt), &ranksNew);CHKERRQ(ierr); 3837 ierr = PetscMalloc(numLeaves * sizeof(PetscInt), &localPointsNew);CHKERRQ(ierr); 3838 ierr = PetscMalloc(numLeaves * sizeof(PetscSFNode), &remotePointsNew);CHKERRQ(ierr); 3839 for (l = 0; l < numLeaves; ++l) { 3840 ranksNew[l] = ranks[l]; 3841 localPointsNew[l] = l; 3842 remotePointsNew[l].index = 0; 3843 remotePointsNew[l].rank = ranksNew[l]; 3844 } 3845 ierr = PetscFree(ranks);CHKERRQ(ierr); 3846 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr); 3847 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 3848 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 3849 ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 3850 PetscFunctionReturn(0); 3851 } 3852 3853 #undef __FUNCT__ 3854 #define __FUNCT__ "CellRefinerCreateSF" 3855 PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 3856 { 3857 PetscSF sf, sfNew, sfProcess; 3858 IS processRanks; 3859 MPI_Datatype depthType; 3860 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 3861 const PetscInt *localPoints, *neighbors; 3862 const PetscSFNode *remotePoints; 3863 PetscInt *localPointsNew; 3864 PetscSFNode *remotePointsNew; 3865 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 3866 PetscInt depth, numNeighbors, pStartNew, pEndNew, cStart, cStartNew, cEnd, cMax, vStart, vStartNew, vEnd, vMax, fStart, fStartNew, fEnd, fMax, eStart, eStartNew, eEnd, eMax, r, n; 3867 PetscErrorCode ierr; 3868 3869 PetscFunctionBegin; 3870 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 3871 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3872 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 3873 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 3874 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 3875 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 3876 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 3877 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 3878 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 3879 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 3880 /* Caculate size of new SF */ 3881 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 3882 if (numRoots < 0) PetscFunctionReturn(0); 3883 for (l = 0; l < numLeaves; ++l) { 3884 const PetscInt p = localPoints[l]; 3885 3886 switch (refiner) { 3887 case 1: 3888 /* Simplicial 2D */ 3889 if ((p >= vStart) && (p < vEnd)) { 3890 /* Old vertices stay the same */ 3891 ++numLeavesNew; 3892 } else if ((p >= fStart) && (p < fEnd)) { 3893 /* Old faces add new faces and vertex */ 3894 numLeavesNew += 2 + 1; 3895 } else if ((p >= cStart) && (p < cEnd)) { 3896 /* Old cells add new cells and interior faces */ 3897 numLeavesNew += 4 + 3; 3898 } 3899 break; 3900 case 2: 3901 /* Hex 2D */ 3902 if ((p >= vStart) && (p < vEnd)) { 3903 /* Old vertices stay the same */ 3904 ++numLeavesNew; 3905 } else if ((p >= fStart) && (p < fEnd)) { 3906 /* Old faces add new faces and vertex */ 3907 numLeavesNew += 2 + 1; 3908 } else if ((p >= cStart) && (p < cEnd)) { 3909 /* Old cells add new cells, interior faces, and vertex */ 3910 numLeavesNew += 4 + 4 + 1; 3911 } 3912 break; 3913 case 5: 3914 /* Simplicial 3D */ 3915 if ((p >= vStart) && (p < vEnd)) { 3916 /* Old vertices stay the same */ 3917 ++numLeavesNew; 3918 } else if ((p >= eStart) && (p < eEnd)) { 3919 /* Old edges add new edges and vertex */ 3920 numLeavesNew += 2 + 1; 3921 } else if ((p >= fStart) && (p < fEnd)) { 3922 /* Old faces add new faces and face edges */ 3923 numLeavesNew += 4 + 3; 3924 } else if ((p >= cStart) && (p < cEnd)) { 3925 /* Old cells add new cells and interior faces and edges */ 3926 numLeavesNew += 8 + 8 + 1; 3927 } 3928 break; 3929 case 7: 3930 /* Hybrid Simplicial 3D */ 3931 if ((p >= vStart) && (p < vEnd)) { 3932 /* Interior vertices stay the same */ 3933 ++numLeavesNew; 3934 } else if ((p >= eStart) && (p < eMax)) { 3935 /* Interior edges add new edges and vertex */ 3936 numLeavesNew += 2 + 1; 3937 } else if ((p >= eMax) && (p < eEnd)) { 3938 /* Hybrid edges stay the same */ 3939 ++numLeavesNew; 3940 } else if ((p >= fStart) && (p < fMax)) { 3941 /* Interior faces add new faces and edges */ 3942 numLeavesNew += 4 + 3; 3943 } else if ((p >= fMax) && (p < fEnd)) { 3944 /* Hybrid faces add new faces and edges */ 3945 numLeavesNew += 2 + 1; 3946 } else if ((p >= cStart) && (p < cMax)) { 3947 /* Interior cells add new cells, faces, and edges */ 3948 numLeavesNew += 8 + 8 + 1; 3949 } else if ((p >= cMax) && (p < cEnd)) { 3950 /* Hybrid cells add new cells and faces */ 3951 numLeavesNew += 4 + 3; 3952 } 3953 break; 3954 case 6: 3955 /* Hex 3D */ 3956 if ((p >= vStart) && (p < vEnd)) { 3957 /* Old vertices stay the same */ 3958 ++numLeavesNew; 3959 } else if ((p >= eStart) && (p < eEnd)) { 3960 /* Old edges add new edges, and vertex */ 3961 numLeavesNew += 2 + 1; 3962 } else if ((p >= fStart) && (p < fEnd)) { 3963 /* Old faces add new faces, edges, and vertex */ 3964 numLeavesNew += 4 + 4 + 1; 3965 } else if ((p >= cStart) && (p < cEnd)) { 3966 /* Old cells add new cells, faces, edges, and vertex */ 3967 numLeavesNew += 8 + 12 + 6 + 1; 3968 } 3969 break; 3970 default: 3971 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 3972 } 3973 } 3974 /* Communicate depthSizes for each remote rank */ 3975 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 3976 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 3977 ierr = PetscMalloc5((depth+1)*numNeighbors,PetscInt,&rdepthSize,numNeighbors,PetscInt,&rvStartNew,numNeighbors,PetscInt,&reStartNew,numNeighbors,PetscInt,&rfStartNew,numNeighbors,PetscInt,&rcStartNew);CHKERRQ(ierr); 3978 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); 3979 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 3980 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 3981 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 3982 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 3983 for (n = 0; n < numNeighbors; ++n) { 3984 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 3985 } 3986 depthSizeOld[depth] = cMax; 3987 depthSizeOld[0] = vMax; 3988 depthSizeOld[depth-1] = fMax; 3989 depthSizeOld[1] = eMax; 3990 3991 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 3992 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 3993 3994 depthSizeOld[depth] = cEnd - cStart; 3995 depthSizeOld[0] = vEnd - vStart; 3996 depthSizeOld[depth-1] = fEnd - fStart; 3997 depthSizeOld[1] = eEnd - eStart; 3998 3999 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 4000 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 4001 for (n = 0; n < numNeighbors; ++n) { 4002 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 4003 } 4004 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 4005 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 4006 /* Calculate new point SF */ 4007 ierr = PetscMalloc(numLeavesNew * sizeof(PetscInt), &localPointsNew);CHKERRQ(ierr); 4008 ierr = PetscMalloc(numLeavesNew * sizeof(PetscSFNode), &remotePointsNew);CHKERRQ(ierr); 4009 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 4010 for (l = 0, m = 0; l < numLeaves; ++l) { 4011 PetscInt p = localPoints[l]; 4012 PetscInt rp = remotePoints[l].index, n; 4013 PetscMPIInt rrank = remotePoints[l].rank; 4014 4015 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 4016 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 4017 switch (refiner) { 4018 case 1: 4019 /* Simplicial 2D */ 4020 if ((p >= vStart) && (p < vEnd)) { 4021 /* Old vertices stay the same */ 4022 localPointsNew[m] = vStartNew + (p - vStart); 4023 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4024 remotePointsNew[m].rank = rrank; 4025 ++m; 4026 } else if ((p >= fStart) && (p < fEnd)) { 4027 /* Old faces add new faces and vertex */ 4028 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 4029 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 4030 remotePointsNew[m].rank = rrank; 4031 ++m; 4032 for (r = 0; r < 2; ++r, ++m) { 4033 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 4034 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 4035 remotePointsNew[m].rank = rrank; 4036 } 4037 } else if ((p >= cStart) && (p < cEnd)) { 4038 /* Old cells add new cells and interior faces */ 4039 for (r = 0; r < 4; ++r, ++m) { 4040 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4041 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4042 remotePointsNew[m].rank = rrank; 4043 } 4044 for (r = 0; r < 3; ++r, ++m) { 4045 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 4046 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 4047 remotePointsNew[m].rank = rrank; 4048 } 4049 } 4050 break; 4051 case 2: 4052 /* Hex 2D */ 4053 if ((p >= vStart) && (p < vEnd)) { 4054 /* Old vertices stay the same */ 4055 localPointsNew[m] = vStartNew + (p - vStart); 4056 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4057 remotePointsNew[m].rank = rrank; 4058 ++m; 4059 } else if ((p >= fStart) && (p < fEnd)) { 4060 /* Old faces add new faces and vertex */ 4061 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 4062 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 4063 remotePointsNew[m].rank = rrank; 4064 ++m; 4065 for (r = 0; r < 2; ++r, ++m) { 4066 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 4067 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 4068 remotePointsNew[m].rank = rrank; 4069 } 4070 } else if ((p >= cStart) && (p < cEnd)) { 4071 /* Old cells add new cells, interior faces, and vertex */ 4072 for (r = 0; r < 4; ++r, ++m) { 4073 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4074 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4075 remotePointsNew[m].rank = rrank; 4076 } 4077 for (r = 0; r < 4; ++r, ++m) { 4078 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 4079 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r; 4080 remotePointsNew[m].rank = rrank; 4081 } 4082 for (r = 0; r < 1; ++r, ++m) { 4083 localPointsNew[m] = vStartNew + (fEnd - fStart) + (p - cStart) + r; 4084 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 4085 remotePointsNew[m].rank = rrank; 4086 } 4087 } 4088 break; 4089 case 3: 4090 /* Hybrid simplicial 2D */ 4091 if ((p >= vStart) && (p < vEnd)) { 4092 /* Old vertices stay the same */ 4093 localPointsNew[m] = vStartNew + (p - vStart); 4094 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4095 remotePointsNew[m].rank = rrank; 4096 ++m; 4097 } else if ((p >= fStart) && (p < fMax)) { 4098 /* Old interior faces add new faces and vertex */ 4099 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 4100 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 4101 remotePointsNew[m].rank = rrank; 4102 ++m; 4103 for (r = 0; r < 2; ++r, ++m) { 4104 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 4105 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 4106 remotePointsNew[m].rank = rrank; 4107 } 4108 } else if ((p >= fMax) && (p < fEnd)) { 4109 /* Old hybrid faces stay the same */ 4110 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 4111 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 4112 remotePointsNew[m].rank = rrank; 4113 ++m; 4114 } else if ((p >= cStart) && (p < cMax)) { 4115 /* Old interior cells add new cells and interior faces */ 4116 for (r = 0; r < 4; ++r, ++m) { 4117 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4118 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4119 remotePointsNew[m].rank = rrank; 4120 } 4121 for (r = 0; r < 3; ++r, ++m) { 4122 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 4123 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 4124 remotePointsNew[m].rank = rrank; 4125 } 4126 } else if ((p >= cStart) && (p < cMax)) { 4127 /* Old hybrid cells add new cells and hybrid face */ 4128 for (r = 0; r < 2; ++r, ++m) { 4129 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4130 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4131 remotePointsNew[m].rank = rrank; 4132 } 4133 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 4134 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]); 4135 remotePointsNew[m].rank = rrank; 4136 ++m; 4137 } 4138 break; 4139 case 5: 4140 /* Simplicial 3D */ 4141 if ((p >= vStart) && (p < vEnd)) { 4142 /* Old vertices stay the same */ 4143 localPointsNew[m] = vStartNew + (p - vStart); 4144 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4145 remotePointsNew[m].rank = rrank; 4146 ++m; 4147 } else if ((p >= eStart) && (p < eEnd)) { 4148 /* Old edges add new edges and vertex */ 4149 for (r = 0; r < 2; ++r, ++m) { 4150 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 4151 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 4152 remotePointsNew[m].rank = rrank; 4153 } 4154 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 4155 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 4156 remotePointsNew[m].rank = rrank; 4157 ++m; 4158 } else if ((p >= fStart) && (p < fEnd)) { 4159 /* Old faces add new faces and face edges */ 4160 for (r = 0; r < 4; ++r, ++m) { 4161 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 4162 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 4163 remotePointsNew[m].rank = rrank; 4164 } 4165 for (r = 0; r < 3; ++r, ++m) { 4166 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 4167 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*3 + r; 4168 remotePointsNew[m].rank = rrank; 4169 } 4170 } else if ((p >= cStart) && (p < cEnd)) { 4171 /* Old cells add new cells and interior faces and edges */ 4172 for (r = 0; r < 8; ++r, ++m) { 4173 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 4174 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 4175 remotePointsNew[m].rank = rrank; 4176 } 4177 for (r = 0; r < 8; ++r, ++m) { 4178 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 4179 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*8 + r; 4180 remotePointsNew[m].rank = rrank; 4181 } 4182 for (r = 0; r < 1; ++r, ++m) { 4183 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 4184 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*1 + r; 4185 remotePointsNew[m].rank = rrank; 4186 } 4187 } 4188 break; 4189 case 7: 4190 /* Hybrid Simplicial 3D */ 4191 if ((p >= vStart) && (p < vEnd)) { 4192 /* Interior vertices stay the same */ 4193 localPointsNew[m] = vStartNew + (p - vStart); 4194 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4195 remotePointsNew[m].rank = rrank; 4196 ++m; 4197 } else if ((p >= eStart) && (p < eMax)) { 4198 /* Interior edges add new edges and vertex */ 4199 for (r = 0; r < 2; ++r, ++m) { 4200 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 4201 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 4202 remotePointsNew[m].rank = rrank; 4203 } 4204 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 4205 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 4206 remotePointsNew[m].rank = rrank; 4207 ++m; 4208 } else if ((p >= eMax) && (p < eEnd)) { 4209 /* Hybrid edges stay the same */ 4210 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 4211 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]); 4212 remotePointsNew[m].rank = rrank; 4213 ++m; 4214 } else if ((p >= fStart) && (p < fMax)) { 4215 /* Interior faces add new faces and edges */ 4216 for (r = 0; r < 4; ++r, ++m) { 4217 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 4218 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 4219 remotePointsNew[m].rank = rrank; 4220 } 4221 for (r = 0; r < 3; ++r, ++m) { 4222 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 4223 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 4224 remotePointsNew[m].rank = rrank; 4225 } 4226 } else if ((p >= fMax) && (p < fEnd)) { 4227 /* Hybrid faces add new faces and edges */ 4228 for (r = 0; r < 2; ++r, ++m) { 4229 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fStart)*2 + r; 4230 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; 4231 remotePointsNew[m].rank = rrank; 4232 } 4233 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart) + (cMax - cStart) + (fEnd - fMax); 4234 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]); 4235 remotePointsNew[m].rank = rrank; 4236 } else if ((p >= cStart) && (p < cMax)) { 4237 /* Interior cells add new cells, faces, and edges */ 4238 for (r = 0; r < 8; ++r, ++m) { 4239 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 4240 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 4241 remotePointsNew[m].rank = rrank; 4242 } 4243 for (r = 0; r < 8; ++r, ++m) { 4244 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 4245 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 4246 remotePointsNew[m].rank = rrank; 4247 } 4248 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + r; 4249 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; 4250 remotePointsNew[m].rank = rrank; 4251 } else if ((p >= cMax) && (p < cEnd)) { 4252 /* Hybrid cells add new cells and faces */ 4253 for (r = 0; r < 4; ++r, ++m) { 4254 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 4255 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 4256 remotePointsNew[m].rank = rrank; 4257 } 4258 for (r = 0; r < 3; ++r, ++m) { 4259 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*4 + (p - cMax)*3 + r; 4260 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; 4261 remotePointsNew[m].rank = rrank; 4262 } 4263 } 4264 break; 4265 case 6: 4266 /* Hex 3D */ 4267 if ((p >= vStart) && (p < vEnd)) { 4268 /* Old vertices stay the same */ 4269 localPointsNew[m] = vStartNew + (p - vStart); 4270 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4271 remotePointsNew[m].rank = rrank; 4272 ++m; 4273 } else if ((p >= eStart) && (p < eEnd)) { 4274 /* Old edges add new edges and vertex */ 4275 for (r = 0; r < 2; ++r, ++m) { 4276 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 4277 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 4278 remotePointsNew[m].rank = rrank; 4279 } 4280 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 4281 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 4282 remotePointsNew[m].rank = rrank; 4283 ++m; 4284 } else if ((p >= fStart) && (p < fEnd)) { 4285 /* Old faces add new faces, edges, and vertex */ 4286 for (r = 0; r < 4; ++r, ++m) { 4287 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 4288 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 4289 remotePointsNew[m].rank = rrank; 4290 } 4291 for (r = 0; r < 4; ++r, ++m) { 4292 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 4293 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*4 + r; 4294 remotePointsNew[m].rank = rrank; 4295 } 4296 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 4297 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]); 4298 remotePointsNew[m].rank = rrank; 4299 ++m; 4300 } else if ((p >= cStart) && (p < cEnd)) { 4301 /* Old cells add new cells, faces, edges, and vertex */ 4302 for (r = 0; r < 8; ++r, ++m) { 4303 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 4304 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 4305 remotePointsNew[m].rank = rrank; 4306 } 4307 for (r = 0; r < 12; ++r, ++m) { 4308 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 4309 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*12 + r; 4310 remotePointsNew[m].rank = rrank; 4311 } 4312 for (r = 0; r < 6; ++r, ++m) { 4313 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 4314 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*6 + r; 4315 remotePointsNew[m].rank = rrank; 4316 } 4317 for (r = 0; r < 1; ++r, ++m) { 4318 localPointsNew[m] = vStartNew + (eEnd - eStart) + (fEnd - fStart) + (p - cStart) + r; 4319 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 4320 remotePointsNew[m].rank = rrank; 4321 } 4322 } 4323 break; 4324 default: 4325 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 4326 } 4327 } 4328 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 4329 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 4330 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 4331 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 4332 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 4333 PetscFunctionReturn(0); 4334 } 4335 4336 #undef __FUNCT__ 4337 #define __FUNCT__ "CellRefinerCreateLabels" 4338 PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 4339 { 4340 PetscInt numLabels, l; 4341 PetscInt depth, newp, cStart, cStartNew, cEnd, cMax, vStart, vStartNew, vEnd, vMax, fStart, fStartNew, fEnd, fMax, eStart, eStartNew, eEnd, eMax, r; 4342 PetscErrorCode ierr; 4343 4344 PetscFunctionBegin; 4345 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 4346 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 4347 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 4348 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 4349 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 4350 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 4351 ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 4352 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 4353 switch (refiner) { 4354 case 0: break; 4355 case 7: 4356 case 8: 4357 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 4358 case 3: 4359 case 4: 4360 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 4361 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 4362 } 4363 for (l = 0; l < numLabels; ++l) { 4364 DMLabel label, labelNew; 4365 const char *lname; 4366 PetscBool isDepth; 4367 IS valueIS; 4368 const PetscInt *values; 4369 PetscInt numValues, val; 4370 4371 ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr); 4372 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 4373 if (isDepth) continue; 4374 ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr); 4375 ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr); 4376 ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 4377 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 4378 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 4379 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 4380 for (val = 0; val < numValues; ++val) { 4381 IS pointIS; 4382 const PetscInt *points; 4383 PetscInt numPoints, n; 4384 4385 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 4386 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 4387 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 4388 for (n = 0; n < numPoints; ++n) { 4389 const PetscInt p = points[n]; 4390 switch (refiner) { 4391 case 1: 4392 /* Simplicial 2D */ 4393 if ((p >= vStart) && (p < vEnd)) { 4394 /* Old vertices stay the same */ 4395 newp = vStartNew + (p - vStart); 4396 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4397 } else if ((p >= fStart) && (p < fEnd)) { 4398 /* Old faces add new faces and vertex */ 4399 newp = vStartNew + (vEnd - vStart) + (p - fStart); 4400 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4401 for (r = 0; r < 2; ++r) { 4402 newp = fStartNew + (p - fStart)*2 + r; 4403 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4404 } 4405 } else if ((p >= cStart) && (p < cEnd)) { 4406 /* Old cells add new cells and interior faces */ 4407 for (r = 0; r < 4; ++r) { 4408 newp = cStartNew + (p - cStart)*4 + r; 4409 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4410 } 4411 for (r = 0; r < 3; ++r) { 4412 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 4413 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4414 } 4415 } 4416 break; 4417 case 2: 4418 /* Hex 2D */ 4419 if ((p >= vStart) && (p < vEnd)) { 4420 /* Old vertices stay the same */ 4421 newp = vStartNew + (p - vStart); 4422 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4423 } else if ((p >= fStart) && (p < fEnd)) { 4424 /* Old faces add new faces and vertex */ 4425 newp = vStartNew + (vEnd - vStart) + (p - fStart); 4426 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4427 for (r = 0; r < 2; ++r) { 4428 newp = fStartNew + (p - fStart)*2 + r; 4429 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4430 } 4431 } else if ((p >= cStart) && (p < cEnd)) { 4432 /* Old cells add new cells and interior faces and vertex */ 4433 for (r = 0; r < 4; ++r) { 4434 newp = cStartNew + (p - cStart)*4 + r; 4435 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4436 } 4437 for (r = 0; r < 4; ++r) { 4438 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 4439 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4440 } 4441 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 4442 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4443 } 4444 break; 4445 case 3: 4446 /* Hybrid simplicial 2D */ 4447 if ((p >= vStart) && (p < vEnd)) { 4448 /* Old vertices stay the same */ 4449 newp = vStartNew + (p - vStart); 4450 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4451 } else if ((p >= fStart) && (p < fMax)) { 4452 /* Old interior faces add new faces and vertex */ 4453 newp = vStartNew + (vEnd - vStart) + (p - fStart); 4454 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4455 for (r = 0; r < 2; ++r) { 4456 newp = fStartNew + (p - fStart)*2 + r; 4457 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4458 } 4459 } else if ((p >= fMax) && (p < fEnd)) { 4460 /* Old hybrid faces stay the same */ 4461 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 4462 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4463 } else if ((p >= cStart) && (p < cMax)) { 4464 /* Old interior cells add new cells and interior faces */ 4465 for (r = 0; r < 4; ++r) { 4466 newp = cStartNew + (p - cStart)*4 + r; 4467 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4468 } 4469 for (r = 0; r < 3; ++r) { 4470 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 4471 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4472 } 4473 } else if ((p >= cMax) && (p < cEnd)) { 4474 /* Old hybrid cells add new cells and hybrid face */ 4475 for (r = 0; r < 2; ++r) { 4476 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 4477 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4478 } 4479 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 4480 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4481 } 4482 break; 4483 case 5: 4484 /* Simplicial 3D */ 4485 if ((p >= vStart) && (p < vEnd)) { 4486 /* Old vertices stay the same */ 4487 newp = vStartNew + (p - vStart); 4488 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4489 } else if ((p >= eStart) && (p < eEnd)) { 4490 /* Old edges add new edges and vertex */ 4491 for (r = 0; r < 2; ++r) { 4492 newp = eStartNew + (p - eStart)*2 + r; 4493 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4494 } 4495 newp = vStartNew + (vEnd - vStart) + (p - eStart); 4496 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4497 } else if ((p >= fStart) && (p < fEnd)) { 4498 /* Old faces add new faces and edges */ 4499 for (r = 0; r < 4; ++r) { 4500 newp = fStartNew + (p - fStart)*4 + r; 4501 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4502 } 4503 for (r = 0; r < 3; ++r) { 4504 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 4505 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4506 } 4507 } else if ((p >= cStart) && (p < cEnd)) { 4508 /* Old cells add new cells and interior faces and edges */ 4509 for (r = 0; r < 8; ++r) { 4510 newp = cStartNew + (p - cStart)*8 + r; 4511 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4512 } 4513 for (r = 0; r < 8; ++r) { 4514 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 4515 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4516 } 4517 for (r = 0; r < 1; ++r) { 4518 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 4519 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4520 } 4521 } 4522 break; 4523 case 7: 4524 /* Hybrid Simplicial 3D */ 4525 if ((p >= vStart) && (p < vEnd)) { 4526 /* Interior vertices stay the same */ 4527 newp = vStartNew + (p - vStart); 4528 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4529 } else if ((p >= eStart) && (p < eMax)) { 4530 /* Interior edges add new edges and vertex */ 4531 for (r = 0; r < 2; ++r) { 4532 newp = eStartNew + (p - eStart)*2 + r; 4533 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4534 } 4535 newp = vStartNew + (vEnd - vStart) + (p - eStart); 4536 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4537 } else if ((p >= eMax) && (p < eEnd)) { 4538 /* Hybrid edges stay the same */ 4539 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 4540 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4541 } else if ((p >= fStart) && (p < fMax)) { 4542 /* Interior faces add new faces and edges */ 4543 for (r = 0; r < 4; ++r) { 4544 newp = fStartNew + (p - fStart)*4 + r; 4545 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4546 } 4547 for (r = 0; r < 3; ++r) { 4548 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 4549 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4550 } 4551 } else if ((p >= fMax) && (p < fEnd)) { 4552 /* Hybrid faces add new faces and edges */ 4553 for (r = 0; r < 2; ++r) { 4554 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 4555 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4556 } 4557 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 4558 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4559 } else if ((p >= cStart) && (p < cMax)) { 4560 /* Interior cells add new cells, faces, and edges */ 4561 for (r = 0; r < 8; ++r) { 4562 newp = cStartNew + (p - cStart)*8 + r; 4563 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4564 } 4565 for (r = 0; r < 8; ++r) { 4566 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 4567 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4568 } 4569 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 4570 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4571 } else if ((p >= cMax) && (p < cEnd)) { 4572 /* Hybrid cells add new cells and faces */ 4573 for (r = 0; r < 4; ++r) { 4574 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 4575 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4576 } 4577 for (r = 0; r < 3; ++r) { 4578 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 4579 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4580 } 4581 } 4582 break; 4583 case 6: 4584 /* Hex 3D */ 4585 if ((p >= vStart) && (p < vEnd)) { 4586 /* Old vertices stay the same */ 4587 newp = vStartNew + (p - vStart); 4588 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4589 } else if ((p >= eStart) && (p < eEnd)) { 4590 /* Old edges add new edges and vertex */ 4591 for (r = 0; r < 2; ++r) { 4592 newp = eStartNew + (p - eStart)*2 + r; 4593 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4594 } 4595 newp = vStartNew + (vEnd - vStart) + (p - eStart); 4596 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4597 } else if ((p >= fStart) && (p < fEnd)) { 4598 /* Old faces add new faces, edges, and vertex */ 4599 for (r = 0; r < 4; ++r) { 4600 newp = fStartNew + (p - fStart)*4 + r; 4601 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4602 } 4603 for (r = 0; r < 4; ++r) { 4604 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 4605 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4606 } 4607 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 4608 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4609 } else if ((p >= cStart) && (p < cEnd)) { 4610 /* Old cells add new cells, faces, edges, and vertex */ 4611 for (r = 0; r < 8; ++r) { 4612 newp = cStartNew + (p - cStart)*8 + r; 4613 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4614 } 4615 for (r = 0; r < 12; ++r) { 4616 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 4617 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4618 } 4619 for (r = 0; r < 6; ++r) { 4620 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 4621 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4622 } 4623 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 4624 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4625 } 4626 break; 4627 default: 4628 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 4629 } 4630 } 4631 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 4632 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 4633 } 4634 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 4635 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 4636 if (0) { 4637 ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr); 4638 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 4639 ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 4640 } 4641 } 4642 PetscFunctionReturn(0); 4643 } 4644 4645 #undef __FUNCT__ 4646 #define __FUNCT__ "DMPlexRefineUniform_Internal" 4647 /* This will only work for interpolated meshes */ 4648 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 4649 { 4650 DM rdm; 4651 PetscInt *depthSize; 4652 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 4653 PetscErrorCode ierr; 4654 4655 PetscFunctionBegin; 4656 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 4657 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 4658 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 4659 ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr); 4660 /* Calculate number of new points of each depth */ 4661 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 4662 ierr = PetscMalloc((depth+1) * sizeof(PetscInt), &depthSize);CHKERRQ(ierr); 4663 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 4664 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 4665 /* Step 1: Set chart */ 4666 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 4667 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 4668 /* Step 2: Set cone/support sizes */ 4669 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4670 /* Step 3: Setup refined DM */ 4671 ierr = DMSetUp(rdm);CHKERRQ(ierr); 4672 /* Step 4: Set cones and supports */ 4673 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4674 /* Step 5: Stratify */ 4675 ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 4676 /* Step 6: Set coordinates for vertices */ 4677 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4678 /* Step 7: Create pointSF */ 4679 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4680 /* Step 8: Create labels */ 4681 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4682 ierr = PetscFree(depthSize);CHKERRQ(ierr); 4683 4684 *dmRefined = rdm; 4685 PetscFunctionReturn(0); 4686 } 4687 4688 #undef __FUNCT__ 4689 #define __FUNCT__ "DMPlexSetRefinementUniform" 4690 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 4691 { 4692 DM_Plex *mesh = (DM_Plex*) dm->data; 4693 4694 PetscFunctionBegin; 4695 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4696 mesh->refinementUniform = refinementUniform; 4697 PetscFunctionReturn(0); 4698 } 4699 4700 #undef __FUNCT__ 4701 #define __FUNCT__ "DMPlexGetRefinementUniform" 4702 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 4703 { 4704 DM_Plex *mesh = (DM_Plex*) dm->data; 4705 4706 PetscFunctionBegin; 4707 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4708 PetscValidPointer(refinementUniform, 2); 4709 *refinementUniform = mesh->refinementUniform; 4710 PetscFunctionReturn(0); 4711 } 4712 4713 #undef __FUNCT__ 4714 #define __FUNCT__ "DMPlexSetRefinementLimit" 4715 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 4716 { 4717 DM_Plex *mesh = (DM_Plex*) dm->data; 4718 4719 PetscFunctionBegin; 4720 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4721 mesh->refinementLimit = refinementLimit; 4722 PetscFunctionReturn(0); 4723 } 4724 4725 #undef __FUNCT__ 4726 #define __FUNCT__ "DMPlexGetRefinementLimit" 4727 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 4728 { 4729 DM_Plex *mesh = (DM_Plex*) dm->data; 4730 4731 PetscFunctionBegin; 4732 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4733 PetscValidPointer(refinementLimit, 2); 4734 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 4735 *refinementLimit = mesh->refinementLimit; 4736 PetscFunctionReturn(0); 4737 } 4738 4739 #undef __FUNCT__ 4740 #define __FUNCT__ "DMPlexGetCellRefiner_Internal" 4741 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 4742 { 4743 PetscInt dim, cStart, cEnd, coneSize, cMax; 4744 PetscErrorCode ierr; 4745 4746 PetscFunctionBegin; 4747 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 4748 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 4749 if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);} 4750 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 4751 ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 4752 switch (dim) { 4753 case 2: 4754 switch (coneSize) { 4755 case 3: 4756 if (cMax >= 0) *cellRefiner = 3; /* Hybrid */ 4757 else *cellRefiner = 1; /* Triangular */ 4758 break; 4759 case 4: 4760 if (cMax >= 0) *cellRefiner = 4; /* Hybrid */ 4761 else *cellRefiner = 2; /* Quadrilateral */ 4762 break; 4763 default: 4764 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 4765 } 4766 break; 4767 case 3: 4768 switch (coneSize) { 4769 case 4: 4770 if (cMax >= 0) *cellRefiner = 7; /* Hybrid */ 4771 else *cellRefiner = 5; /* Tetrahedral */ 4772 break; 4773 case 6: 4774 if (cMax >= 0) *cellRefiner = 8; /* Hybrid */ 4775 else *cellRefiner = 6; /* hexahedral */ 4776 break; 4777 default: 4778 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 4779 } 4780 break; 4781 default: 4782 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 4783 } 4784 PetscFunctionReturn(0); 4785 } 4786