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