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