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 + (cone[2] - fStart)*4 + 3; 1573 orntNew[1] = ornt[2] < 0 ? -((-(ornt[2]+1)+0)%3+1) : (ornt[2]+0)%3; /* TODO: I do not believe this one */ 1574 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 1575 orntNew[2] = 0; 1576 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 1577 orntNew[3] = 2; 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 + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 1590 orntNew[1] = 1; 1591 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 1592 orntNew[2] = 0; 1593 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 1594 orntNew[3] = ornt[3] < 0 ? -((-(ornt[3]+1)+0)%3+1) : (ornt[3]+0)%3; /* TODO I do not believe this one */ 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 + (cone[0] - fStart)*4 + 3; 1607 orntNew[1] = ornt[0] < 0 ? -((-(ornt[0]+1)+0)%3+1) : ((ornt[0]+1)%3+1); /* TODO: This is wrong I think */ 1608 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 1609 orntNew[2] = -3; 1610 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 1611 orntNew[3] = -2; 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 + 4; 1624 orntNew[1] = -3; 1625 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 1626 orntNew[2] = ornt[2]; 1627 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 1628 orntNew[3] = -3; 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] = 0; 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, *fornt; 2288 PetscInt coneNew[5], orntNew[5]; 2289 2290 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2291 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2292 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 2293 for (r = 0; r < 3; ++r) { 2294 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 2295 orntNew[0] = ornt[0]; 2296 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 2297 orntNew[1] = ornt[1]; 2298 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], (r+2)%3)] - fMax)*2 + (fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? 0 : 1); 2299 orntNew[2] = 0; 2300 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? 1 : 0); 2301 orntNew[3] = 0; 2302 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 2303 orntNew[4] = 0; 2304 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 2305 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 2306 #if 1 2307 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); 2308 for (p = 0; p < 2; ++p) { 2309 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); 2310 } 2311 for (p = 2; p < 5; ++p) { 2312 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); 2313 } 2314 #endif 2315 } 2316 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 2317 orntNew[0] = 0; 2318 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 2319 orntNew[1] = 0; 2320 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 2321 orntNew[2] = 0; 2322 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 2323 orntNew[3] = 0; 2324 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 2325 orntNew[4] = 0; 2326 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2327 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2328 #if 1 2329 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); 2330 for (p = 0; p < 2; ++p) { 2331 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); 2332 } 2333 for (p = 2; p < 5; ++p) { 2334 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); 2335 } 2336 #endif 2337 } 2338 /* Split faces have 3 edges and the same cells as the parent */ 2339 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2340 ierr = PetscMalloc((2 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr); 2341 for (f = fStart; f < fMax; ++f) { 2342 const PetscInt newp = fStartNew + (f - fStart)*4; 2343 const PetscInt *cone, *ornt, *support; 2344 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 2345 2346 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2347 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2348 /* A triangle */ 2349 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 2350 orntNew[0] = ornt[0]; 2351 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 2352 orntNew[1] = -2; 2353 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 2354 orntNew[2] = ornt[2]; 2355 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2356 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2357 #if 1 2358 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); 2359 for (p = 0; p < 3; ++p) { 2360 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); 2361 } 2362 #endif 2363 /* B triangle */ 2364 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 2365 orntNew[0] = ornt[0]; 2366 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 2367 orntNew[1] = ornt[1]; 2368 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 2369 orntNew[2] = -2; 2370 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2371 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2372 #if 1 2373 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); 2374 for (p = 0; p < 3; ++p) { 2375 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); 2376 } 2377 #endif 2378 /* C triangle */ 2379 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 2380 orntNew[0] = -2; 2381 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 2382 orntNew[1] = ornt[1]; 2383 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 2384 orntNew[2] = ornt[2]; 2385 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2386 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2387 #if 1 2388 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); 2389 for (p = 0; p < 3; ++p) { 2390 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); 2391 } 2392 #endif 2393 /* D triangle */ 2394 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 2395 orntNew[0] = 0; 2396 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 2397 orntNew[1] = 0; 2398 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 2399 orntNew[2] = 0; 2400 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2401 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2402 #if 1 2403 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); 2404 for (p = 0; p < 3; ++p) { 2405 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); 2406 } 2407 #endif 2408 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2409 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2410 for (r = 0; r < 4; ++r) { 2411 for (s = 0; s < supportSize; ++s) { 2412 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2413 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2414 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2415 for (c = 0; c < coneSize; ++c) { 2416 if (cone[c] == f) break; 2417 } 2418 if (support[s] < cMax) { 2419 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])); 2420 } else { 2421 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : GetTriSubfaceInverse_Static(ornt[c], r)); 2422 } 2423 } 2424 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 2425 #if 1 2426 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2427 for (p = 0; p < supportSize; ++p) { 2428 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); 2429 } 2430 #endif 2431 } 2432 } 2433 /* Interior cell faces have 3 edges and 2 cells */ 2434 for (c = cStart; c < cMax; ++c) { 2435 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 2436 const PetscInt *cone, *ornt; 2437 PetscInt coneNew[3], orntNew[3]; 2438 PetscInt supportNew[2]; 2439 2440 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2441 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2442 /* Face A: {c, a, d} */ 2443 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+0)%3 : (ornt[0]+2)%3); 2444 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2445 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+0)%3 : (ornt[1]+2)%3); 2446 orntNew[1] = ornt[1] < 0 ? -2 : 0; 2447 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+0)%3 : (ornt[2]+2)%3); 2448 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2449 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2450 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2451 #if 1 2452 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2453 for (p = 0; p < 3; ++p) { 2454 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); 2455 } 2456 #endif 2457 supportNew[0] = (c - cStart)*8 + 0; 2458 supportNew[1] = (c - cStart)*8 + 0+4; 2459 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2460 #if 1 2461 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2462 for (p = 0; p < 2; ++p) { 2463 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); 2464 } 2465 #endif 2466 ++newp; 2467 /* Face B: {a, b, e} */ 2468 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+2)%3 : (ornt[0]+0)%3); 2469 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2470 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+2)%3 : (ornt[3]+0)%3); 2471 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2472 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+1)%3 : (ornt[1]+1)%3); 2473 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2474 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2475 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2476 #if 1 2477 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); 2478 for (p = 0; p < 3; ++p) { 2479 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); 2480 } 2481 #endif 2482 supportNew[0] = (c - cStart)*8 + 1; 2483 supportNew[1] = (c - cStart)*8 + 1+4; 2484 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2485 #if 1 2486 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2487 for (p = 0; p < 2; ++p) { 2488 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); 2489 } 2490 #endif 2491 ++newp; 2492 /* Face C: {c, f, b} */ 2493 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+2)%3 : (ornt[2]+0)%3); 2494 orntNew[0] = ornt[2] < 0 ? -2 : 0; 2495 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+0)%3 : (ornt[3]+2)%3); 2496 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2497 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+1)%3 : (ornt[0]+1)%3); 2498 orntNew[2] = ornt[0] < 0 ? -2 : 0; 2499 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2500 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2501 #if 1 2502 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2503 for (p = 0; p < 3; ++p) { 2504 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); 2505 } 2506 #endif 2507 supportNew[0] = (c - cStart)*8 + 2; 2508 supportNew[1] = (c - cStart)*8 + 2+4; 2509 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2510 #if 1 2511 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2512 for (p = 0; p < 2; ++p) { 2513 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); 2514 } 2515 #endif 2516 ++newp; 2517 /* Face D: {d, e, f} */ 2518 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+2)%3 : (ornt[1]+0)%3); 2519 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2520 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+1)%3 : (ornt[3]+1)%3); 2521 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2522 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+1)%3 : (ornt[2]+1)%3); 2523 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2524 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2525 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2526 #if 1 2527 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2528 for (p = 0; p < 3; ++p) { 2529 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); 2530 } 2531 #endif 2532 supportNew[0] = (c - cStart)*8 + 3; 2533 supportNew[1] = (c - cStart)*8 + 3+4; 2534 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2535 #if 1 2536 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2537 for (p = 0; p < 2; ++p) { 2538 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); 2539 } 2540 #endif 2541 ++newp; 2542 /* Face E: {d, f, a} */ 2543 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+1)%3 : (ornt[2]+1)%3); 2544 orntNew[0] = ornt[2] < 0 ? 0 : -2; 2545 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2546 orntNew[1] = 0; 2547 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+0)%3 : (ornt[1]+2)%3); 2548 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2549 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2550 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2551 #if 1 2552 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2553 for (p = 0; p < 3; ++p) { 2554 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); 2555 } 2556 #endif 2557 supportNew[0] = (c - cStart)*8 + 0+4; 2558 supportNew[1] = (c - cStart)*8 + 3+4; 2559 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2560 #if 1 2561 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2562 for (p = 0; p < 2; ++p) { 2563 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); 2564 } 2565 #endif 2566 ++newp; 2567 /* Face F: {c, a, f} */ 2568 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+0)%3 : (ornt[0]+2)%3); 2569 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2570 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2571 orntNew[1] = -2; 2572 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+2)%3 : (ornt[2]+0)%3); 2573 orntNew[2] = ornt[1] < 0 ? 0 : -2; 2574 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2575 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2576 #if 1 2577 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2578 for (p = 0; p < 3; ++p) { 2579 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); 2580 } 2581 #endif 2582 supportNew[0] = (c - cStart)*8 + 0+4; 2583 supportNew[1] = (c - cStart)*8 + 2+4; 2584 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2585 #if 1 2586 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2587 for (p = 0; p < 2; ++p) { 2588 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); 2589 } 2590 #endif 2591 ++newp; 2592 /* Face G: {e, a, f} */ 2593 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+1)%3 : (ornt[1]+1)%3); 2594 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2595 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2596 orntNew[1] = -2; 2597 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+1)%3 : (ornt[3]+1)%3); 2598 orntNew[2] = ornt[3] < 0 ? 0 : -2; 2599 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2600 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2601 #if 1 2602 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2603 for (p = 0; p < 3; ++p) { 2604 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); 2605 } 2606 #endif 2607 supportNew[0] = (c - cStart)*8 + 1+4; 2608 supportNew[1] = (c - cStart)*8 + 3+4; 2609 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2610 #if 1 2611 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2612 for (p = 0; p < 2; ++p) { 2613 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); 2614 } 2615 #endif 2616 ++newp; 2617 /* Face H: {a, b, f} */ 2618 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+2)%3 : (ornt[0]+0)%3); 2619 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2620 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+0)%3 : (ornt[3]+2)%3); 2621 orntNew[1] = ornt[3] < 0 ? 0 : -2; 2622 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2623 orntNew[2] = 0; 2624 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2625 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2626 #if 1 2627 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2628 for (p = 0; p < 3; ++p) { 2629 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); 2630 } 2631 #endif 2632 supportNew[0] = (c - cStart)*8 + 1+4; 2633 supportNew[1] = (c - cStart)*8 + 2+4; 2634 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2635 #if 1 2636 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2637 for (p = 0; p < 2; ++p) { 2638 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); 2639 } 2640 #endif 2641 ++newp; 2642 } 2643 /* Hybrid split faces have 4 edges and same cells */ 2644 for (f = fMax; f < fEnd; ++f) { 2645 const PetscInt *cone, *ornt, *support; 2646 PetscInt coneNew[4], orntNew[4]; 2647 PetscInt supportNew[2], size, s, c; 2648 2649 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2650 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2651 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2652 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2653 for (r = 0; r < 2; ++r) { 2654 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 2655 2656 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 2657 orntNew[0] = ornt[0]; 2658 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 2659 orntNew[1] = ornt[1]; 2660 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 2661 orntNew[2+r] = 0; 2662 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 2663 orntNew[3-r] = 0; 2664 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2665 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2666 #if 1 2667 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 2668 for (p = 0; p < 2; ++p) { 2669 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); 2670 } 2671 for (p = 2; p < 4; ++p) { 2672 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); 2673 } 2674 #endif 2675 for (s = 0; s < size; ++s) { 2676 const PetscInt *coneCell, *orntCell, *fornt; 2677 2678 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 2679 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 2680 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 2681 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 2682 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 2683 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (fornt[c-2] < 0 ? 1-r : r))%3; 2684 } 2685 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2686 #if 1 2687 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 2688 for (p = 0; p < size; ++p) { 2689 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); 2690 } 2691 #endif 2692 } 2693 } 2694 /* Hybrid cell faces have 4 edges and 2 cells */ 2695 for (c = cMax; c < cEnd; ++c) { 2696 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 2697 const PetscInt *cone, *ornt; 2698 PetscInt coneNew[4], orntNew[4]; 2699 PetscInt supportNew[2]; 2700 2701 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2702 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2703 for (r = 0; r < 3; ++r) { 2704 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], (r+2)%3); 2705 orntNew[0] = 0; 2706 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], (r+2)%3); 2707 orntNew[1] = 0; 2708 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+GetTriSubface_Static(ornt[0], (r+2)%3)] - fMax); 2709 orntNew[2] = 0; 2710 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+GetTriSubface_Static(ornt[0], r)] - fMax); 2711 orntNew[3] = 0; 2712 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 2713 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 2714 #if 1 2715 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); 2716 for (p = 0; p < 2; ++p) { 2717 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); 2718 } 2719 for (p = 2; p < 4; ++p) { 2720 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); 2721 } 2722 #endif 2723 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 2724 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 2725 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 2726 #if 1 2727 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); 2728 for (p = 0; p < 2; ++p) { 2729 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); 2730 } 2731 #endif 2732 } 2733 } 2734 /* Interior split edges have 2 vertices and the same faces as the parent */ 2735 for (e = eStart; e < eMax; ++e) { 2736 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 2737 2738 for (r = 0; r < 2; ++r) { 2739 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 2740 const PetscInt *cone, *ornt, *support; 2741 PetscInt coneNew[2], coneSize, c, supportSize, s; 2742 2743 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 2744 coneNew[0] = vStartNew + (cone[0] - vStart); 2745 coneNew[1] = vStartNew + (cone[1] - vStart); 2746 coneNew[(r+1)%2] = newv; 2747 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2748 #if 1 2749 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2750 for (p = 0; p < 2; ++p) { 2751 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); 2752 } 2753 #endif 2754 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 2755 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2756 for (s = 0; s < supportSize; ++s) { 2757 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2758 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2759 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2760 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 2761 if (support[s] < fMax) { 2762 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 2763 } else { 2764 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 2765 } 2766 } 2767 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2768 #if 1 2769 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2770 for (p = 0; p < supportSize; ++p) { 2771 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); 2772 } 2773 #endif 2774 } 2775 } 2776 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 2777 for (f = fStart; f < fMax; ++f) { 2778 const PetscInt *cone, *ornt, *support; 2779 PetscInt coneSize, supportSize, s; 2780 2781 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2782 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2783 for (r = 0; r < 3; ++r) { 2784 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 2785 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 2786 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 2787 -1, -1, 1, 6, 0, 4, 2788 2, 5, 3, 4, -1, -1, 2789 -1, -1, 3, 6, 2, 7}; 2790 2791 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2792 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 2793 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 2794 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2795 #if 1 2796 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2797 for (p = 0; p < 2; ++p) { 2798 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); 2799 } 2800 #endif 2801 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 2802 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 2803 for (s = 0; s < supportSize; ++s) { 2804 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2805 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2806 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2807 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 2808 if (support[s] < cMax) { 2809 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 2810 er = ornt[c] < 0 ? (-(ornt[c]+1) + 2-r)%3 : (ornt[c] + r)%3; 2811 if (er == eint[c]) { 2812 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 2813 } else { 2814 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 2815 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 2816 } 2817 } else { 2818 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (GetTriSubfaceInverse_Static(ornt[c], r) + 1)%3; 2819 } 2820 } 2821 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2822 #if 1 2823 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2824 for (p = 0; p < intFaces; ++p) { 2825 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); 2826 } 2827 #endif 2828 } 2829 } 2830 /* Interior cell edges have 2 vertices and 4 faces */ 2831 for (c = cStart; c < cMax; ++c) { 2832 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2833 const PetscInt *cone, *ornt, *fcone; 2834 PetscInt coneNew[2], supportNew[4], find; 2835 2836 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2837 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2838 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 2839 find = GetTriEdge_Static(ornt[0], 0); 2840 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2841 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 2842 find = GetTriEdge_Static(ornt[2], 1); 2843 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2844 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2845 #if 1 2846 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2847 for (p = 0; p < 2; ++p) { 2848 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); 2849 } 2850 #endif 2851 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 2852 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 2853 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 2854 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 2855 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2856 #if 1 2857 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2858 for (p = 0; p < 4; ++p) { 2859 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); 2860 } 2861 #endif 2862 } 2863 /* Hybrid edges have two vertices and the same faces */ 2864 for (e = eMax; e < eEnd; ++e) { 2865 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 2866 const PetscInt *cone, *support, *fcone; 2867 PetscInt coneNew[2], size, fsize, s; 2868 2869 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 2870 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 2871 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2872 coneNew[0] = vStartNew + (cone[0] - vStart); 2873 coneNew[1] = vStartNew + (cone[1] - vStart); 2874 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2875 #if 1 2876 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 2877 for (p = 0; p < 2; ++p) { 2878 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); 2879 } 2880 #endif 2881 for (s = 0; s < size; ++s) { 2882 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 2883 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 2884 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 2885 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 2886 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 2887 } 2888 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2889 #if 1 2890 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 2891 for (p = 0; p < size; ++p) { 2892 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); 2893 } 2894 #endif 2895 } 2896 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 2897 for (f = fMax; f < fEnd; ++f) { 2898 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 2899 const PetscInt *cone, *support, *ccone, *cornt; 2900 PetscInt coneNew[2], size, csize, s; 2901 2902 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2903 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2904 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2905 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 2906 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 2907 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2908 #if 1 2909 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 2910 for (p = 0; p < 2; ++p) { 2911 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); 2912 } 2913 #endif 2914 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 2915 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 2916 for (s = 0; s < size; ++s) { 2917 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 2918 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 2919 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 2920 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 2921 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]); 2922 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + GetTriSubfaceInverse_Static(cornt[0], c-2); 2923 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (GetTriSubfaceInverse_Static(cornt[0], c-2) + 1)%3; 2924 } 2925 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2926 #if 1 2927 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 2928 for (p = 0; p < 2+size*2; ++p) { 2929 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); 2930 } 2931 #endif 2932 } 2933 /* Interior vertices have identical supports */ 2934 for (v = vStart; v < vEnd; ++v) { 2935 const PetscInt newp = vStartNew + (v - vStart); 2936 const PetscInt *support, *cone; 2937 PetscInt size, s; 2938 2939 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2940 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2941 for (s = 0; s < size; ++s) { 2942 PetscInt r = 0; 2943 2944 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2945 if (cone[1] == v) r = 1; 2946 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 2947 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 2948 } 2949 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2950 #if 1 2951 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2952 for (p = 0; p < size; ++p) { 2953 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); 2954 } 2955 #endif 2956 } 2957 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 2958 for (e = eStart; e < eMax; ++e) { 2959 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 2960 const PetscInt *cone, *support; 2961 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 2962 2963 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 2964 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2965 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 2966 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 2967 for (s = 0; s < size; ++s) { 2968 PetscInt r = 0; 2969 2970 if (support[s] < fMax) { 2971 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2972 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2973 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 2974 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 2975 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 2976 faceSize += 2; 2977 } else { 2978 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 2979 ++faceSize; 2980 } 2981 } 2982 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2983 for (s = 0; s < starSize*2; s += 2) { 2984 const PetscInt *cone, *ornt; 2985 PetscInt e01, e23; 2986 2987 if ((star[s] >= cStart) && (star[s] < cMax)) { 2988 /* Check edge 0-1 */ 2989 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2990 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2991 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 2992 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 2993 /* Check edge 2-3 */ 2994 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2995 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2996 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 2997 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 2998 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 2999 } 3000 } 3001 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3002 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3003 #if 1 3004 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3005 for (p = 0; p < 2+faceSize+cellSize; ++p) { 3006 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); 3007 } 3008 #endif 3009 } 3010 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3011 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 3012 break; 3013 case 6: 3014 /* Hex 3D */ 3015 /* 3016 Bottom (viewed from top) Top 3017 1---------2---------2 7---------2---------6 3018 | | | | | | 3019 | B 2 C | | H 2 G | 3020 | | | | | | 3021 3----3----0----1----1 3----3----0----1----1 3022 | | | | | | 3023 | A 0 D | | E 0 F | 3024 | | | | | | 3025 0---------0---------3 4---------0---------5 3026 */ 3027 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 3028 for (c = cStart; c < cEnd; ++c) { 3029 const PetscInt newp = (c - cStart)*8; 3030 const PetscInt *cone, *ornt; 3031 PetscInt coneNew[6], orntNew[6]; 3032 3033 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3034 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3035 /* A hex */ 3036 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 3037 orntNew[0] = ornt[0]; 3038 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3039 orntNew[1] = 0; 3040 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 3041 orntNew[2] = ornt[2]; 3042 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3043 orntNew[3] = 0; 3044 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3045 orntNew[4] = 0; 3046 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 3047 orntNew[5] = ornt[5]; 3048 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3049 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3050 #if 1 3051 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); 3052 for (p = 0; p < 6; ++p) { 3053 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); 3054 } 3055 #endif 3056 /* B hex */ 3057 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 3058 orntNew[0] = ornt[0]; 3059 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3060 orntNew[1] = 0; 3061 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3062 orntNew[2] = -3; 3063 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 3064 orntNew[3] = ornt[3]; 3065 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3066 orntNew[4] = 0; 3067 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 3068 orntNew[5] = ornt[5]; 3069 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3070 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3071 #if 1 3072 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); 3073 for (p = 0; p < 6; ++p) { 3074 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); 3075 } 3076 #endif 3077 /* C hex */ 3078 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 3079 orntNew[0] = ornt[0]; 3080 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3081 orntNew[1] = 0; 3082 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3083 orntNew[2] = 0; 3084 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 3085 orntNew[3] = ornt[3]; 3086 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 3087 orntNew[4] = ornt[4]; 3088 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3089 orntNew[5] = -3; 3090 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3091 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3092 #if 1 3093 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); 3094 for (p = 0; p < 6; ++p) { 3095 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); 3096 } 3097 #endif 3098 /* D hex */ 3099 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 3100 orntNew[0] = ornt[0]; 3101 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3102 orntNew[1] = 0; 3103 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 3104 orntNew[2] = ornt[2]; 3105 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3106 orntNew[3] = -3; 3107 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 3108 orntNew[4] = ornt[4]; 3109 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3110 orntNew[5] = -3; 3111 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3112 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3113 #if 1 3114 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); 3115 for (p = 0; p < 6; ++p) { 3116 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); 3117 } 3118 #endif 3119 /* E hex */ 3120 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3121 orntNew[0] = -3; 3122 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 3123 orntNew[1] = ornt[1]; 3124 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 3125 orntNew[2] = ornt[2]; 3126 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3127 orntNew[3] = 0; 3128 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3129 orntNew[4] = 0; 3130 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 3131 orntNew[5] = ornt[5]; 3132 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3133 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3134 #if 1 3135 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); 3136 for (p = 0; p < 6; ++p) { 3137 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); 3138 } 3139 #endif 3140 /* F hex */ 3141 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3142 orntNew[0] = -3; 3143 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 3144 orntNew[1] = ornt[1]; 3145 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 3146 orntNew[2] = ornt[2]; 3147 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3148 orntNew[3] = 0; 3149 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 3150 orntNew[4] = ornt[4]; 3151 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3152 orntNew[5] = -3; 3153 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3154 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3155 #if 1 3156 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); 3157 for (p = 0; p < 6; ++p) { 3158 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); 3159 } 3160 #endif 3161 /* G hex */ 3162 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3163 orntNew[0] = -3; 3164 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 3165 orntNew[1] = ornt[1]; 3166 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3167 orntNew[2] = -3; 3168 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 3169 orntNew[3] = ornt[3]; 3170 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 3171 orntNew[4] = ornt[4]; 3172 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3173 orntNew[5] = 0; 3174 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3175 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3176 #if 1 3177 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); 3178 for (p = 0; p < 6; ++p) { 3179 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); 3180 } 3181 #endif 3182 /* H hex */ 3183 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3184 orntNew[0] = -3; 3185 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 3186 orntNew[1] = ornt[1]; 3187 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3188 orntNew[2] = -3; 3189 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 3190 orntNew[3] = ornt[3]; 3191 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3192 orntNew[4] = -3; 3193 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 3194 orntNew[5] = ornt[5]; 3195 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3196 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3197 #if 1 3198 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); 3199 for (p = 0; p < 6; ++p) { 3200 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); 3201 } 3202 #endif 3203 } 3204 /* Split faces have 4 edges and the same cells as the parent */ 3205 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3206 ierr = PetscMalloc((4 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr); 3207 for (f = fStart; f < fEnd; ++f) { 3208 for (r = 0; r < 4; ++r) { 3209 /* TODO: This can come from GetFaces_Internal() */ 3210 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}; 3211 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 3212 const PetscInt *cone, *ornt, *support; 3213 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 3214 3215 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3216 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3217 coneNew[0] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 3218 orntNew[0] = ornt[(r+3)%4]; 3219 coneNew[1] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 3220 orntNew[1] = ornt[r]; 3221 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 3222 orntNew[2] = 0; 3223 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 3224 orntNew[3] = -2; 3225 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3226 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3227 #if 1 3228 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3229 for (p = 0; p < 4; ++p) { 3230 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); 3231 } 3232 #endif 3233 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3234 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3235 for (s = 0; s < supportSize; ++s) { 3236 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3237 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3238 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3239 for (c = 0; c < coneSize; ++c) { 3240 if (cone[c] == f) break; 3241 } 3242 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubface_Static(ornt[c], r)]; 3243 } 3244 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3245 #if 1 3246 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3247 for (p = 0; p < supportSize; ++p) { 3248 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); 3249 } 3250 #endif 3251 } 3252 } 3253 /* Interior faces have 4 edges and 2 cells */ 3254 for (c = cStart; c < cEnd; ++c) { 3255 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}; 3256 const PetscInt *cone, *ornt; 3257 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 3258 3259 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3260 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3261 /* A-D face */ 3262 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 3263 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 3264 orntNew[0] = -2; 3265 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 3266 orntNew[1] = 0; 3267 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3268 orntNew[2] = 0; 3269 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3270 orntNew[3] = -2; 3271 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3272 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3273 #if 1 3274 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3275 for (p = 0; p < 4; ++p) { 3276 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); 3277 } 3278 #endif 3279 /* C-D face */ 3280 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 3281 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 3282 orntNew[0] = -2; 3283 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 3284 orntNew[1] = 0; 3285 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3286 orntNew[2] = 0; 3287 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3288 orntNew[3] = -2; 3289 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3290 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3291 #if 1 3292 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3293 for (p = 0; p < 4; ++p) { 3294 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); 3295 } 3296 #endif 3297 /* B-C face */ 3298 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 3299 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 3300 orntNew[0] = -2; 3301 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 3302 orntNew[1] = 0; 3303 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3304 orntNew[2] = 0; 3305 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3306 orntNew[3] = -2; 3307 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3308 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3309 #if 1 3310 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3311 for (p = 0; p < 4; ++p) { 3312 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); 3313 } 3314 #endif 3315 /* A-B face */ 3316 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 3317 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 3318 orntNew[0] = -2; 3319 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 3320 orntNew[1] = 0; 3321 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3322 orntNew[2] = 0; 3323 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3324 orntNew[3] = -2; 3325 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3326 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3327 #if 1 3328 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3329 for (p = 0; p < 4; ++p) { 3330 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); 3331 } 3332 #endif 3333 /* E-F face */ 3334 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 3335 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 3336 orntNew[0] = -2; 3337 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 3338 orntNew[1] = 0; 3339 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3340 orntNew[2] = 0; 3341 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3342 orntNew[3] = -2; 3343 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3344 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3345 #if 1 3346 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3347 for (p = 0; p < 4; ++p) { 3348 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); 3349 } 3350 #endif 3351 /* F-G face */ 3352 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 3353 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 3354 orntNew[0] = -2; 3355 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 3356 orntNew[1] = 0; 3357 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3358 orntNew[2] = 0; 3359 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3360 orntNew[3] = -2; 3361 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3362 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3363 #if 1 3364 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3365 for (p = 0; p < 4; ++p) { 3366 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); 3367 } 3368 #endif 3369 /* G-H face */ 3370 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 3371 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 3372 orntNew[0] = -2; 3373 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 3374 orntNew[1] = 0; 3375 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3376 orntNew[2] = 0; 3377 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3378 orntNew[3] = -2; 3379 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3380 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3381 #if 1 3382 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3383 for (p = 0; p < 4; ++p) { 3384 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); 3385 } 3386 #endif 3387 /* E-H face */ 3388 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 3389 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 3390 orntNew[0] = -2; 3391 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 3392 orntNew[1] = 0; 3393 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3394 orntNew[2] = 0; 3395 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3396 orntNew[3] = -2; 3397 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3398 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3399 #if 1 3400 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3401 for (p = 0; p < 4; ++p) { 3402 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); 3403 } 3404 #endif 3405 /* A-E face */ 3406 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 3407 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 3408 orntNew[0] = -2; 3409 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 3410 orntNew[1] = 0; 3411 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3412 orntNew[2] = 0; 3413 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3414 orntNew[3] = -2; 3415 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3416 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3417 #if 1 3418 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3419 for (p = 0; p < 4; ++p) { 3420 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); 3421 } 3422 #endif 3423 /* D-F face */ 3424 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 3425 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 3426 orntNew[0] = -2; 3427 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 3428 orntNew[1] = 0; 3429 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3430 orntNew[2] = 0; 3431 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3432 orntNew[3] = -2; 3433 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3434 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3435 #if 1 3436 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3437 for (p = 0; p < 4; ++p) { 3438 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); 3439 } 3440 #endif 3441 /* C-G face */ 3442 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 3443 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 3444 orntNew[0] = -2; 3445 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 3446 orntNew[1] = 0; 3447 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3448 orntNew[2] = 0; 3449 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3450 orntNew[3] = -2; 3451 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3452 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3453 #if 1 3454 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3455 for (p = 0; p < 4; ++p) { 3456 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); 3457 } 3458 #endif 3459 /* B-H face */ 3460 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 3461 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 3462 orntNew[0] = -2; 3463 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 3464 orntNew[1] = 0; 3465 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3466 orntNew[2] = 0; 3467 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3468 orntNew[3] = -2; 3469 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3470 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3471 #if 1 3472 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3473 for (p = 0; p < 4; ++p) { 3474 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); 3475 } 3476 #endif 3477 for (r = 0; r < 12; ++r) { 3478 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 3479 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 3480 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 3481 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3482 #if 1 3483 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3484 for (p = 0; p < 2; ++p) { 3485 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); 3486 } 3487 #endif 3488 } 3489 } 3490 /* Split edges have 2 vertices and the same faces as the parent */ 3491 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3492 for (e = eStart; e < eEnd; ++e) { 3493 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3494 3495 for (r = 0; r < 2; ++r) { 3496 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3497 const PetscInt *cone, *ornt, *support; 3498 PetscInt coneNew[2], coneSize, c, supportSize, s; 3499 3500 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3501 coneNew[0] = vStartNew + (cone[0] - vStart); 3502 coneNew[1] = vStartNew + (cone[1] - vStart); 3503 coneNew[(r+1)%2] = newv; 3504 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3505 #if 1 3506 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3507 for (p = 0; p < 2; ++p) { 3508 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); 3509 } 3510 #endif 3511 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3512 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3513 for (s = 0; s < supportSize; ++s) { 3514 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3515 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3516 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3517 for (c = 0; c < coneSize; ++c) { 3518 if (cone[c] == e) break; 3519 } 3520 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 3521 } 3522 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3523 #if 1 3524 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3525 for (p = 0; p < supportSize; ++p) { 3526 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); 3527 } 3528 #endif 3529 } 3530 } 3531 /* Face edges have 2 vertices and 2+cells faces */ 3532 for (f = fStart; f < fEnd; ++f) { 3533 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}; 3534 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 3535 const PetscInt *cone, *coneCell, *orntCell, *support; 3536 PetscInt coneNew[2], coneSize, c, supportSize, s; 3537 3538 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3539 for (r = 0; r < 4; ++r) { 3540 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 3541 3542 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 3543 coneNew[1] = newv; 3544 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3545 #if 1 3546 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3547 for (p = 0; p < 2; ++p) { 3548 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); 3549 } 3550 #endif 3551 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3552 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3553 supportRef[0] = fStartNew + (f - fStart)*4 + r; 3554 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 3555 for (s = 0; s < supportSize; ++s) { 3556 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3557 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 3558 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 3559 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 3560 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdge_Static(orntCell[c], r)]; 3561 } 3562 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3563 #if 1 3564 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3565 for (p = 0; p < 2+supportSize; ++p) { 3566 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); 3567 } 3568 #endif 3569 } 3570 } 3571 /* Cell edges have 2 vertices and 4 faces */ 3572 for (c = cStart; c < cEnd; ++c) { 3573 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}; 3574 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 3575 const PetscInt *cone; 3576 PetscInt coneNew[2], supportNew[4]; 3577 3578 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3579 for (r = 0; r < 6; ++r) { 3580 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 3581 3582 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 3583 coneNew[1] = newv; 3584 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3585 #if 1 3586 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3587 for (p = 0; p < 2; ++p) { 3588 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); 3589 } 3590 #endif 3591 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 3592 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3593 #if 1 3594 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3595 for (p = 0; p < 4; ++p) { 3596 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); 3597 } 3598 #endif 3599 } 3600 } 3601 /* Old vertices have identical supports */ 3602 for (v = vStart; v < vEnd; ++v) { 3603 const PetscInt newp = vStartNew + (v - vStart); 3604 const PetscInt *support, *cone; 3605 PetscInt size, s; 3606 3607 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3608 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3609 for (s = 0; s < size; ++s) { 3610 PetscInt r = 0; 3611 3612 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3613 if (cone[1] == v) r = 1; 3614 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3615 } 3616 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3617 #if 1 3618 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3619 for (p = 0; p < size; ++p) { 3620 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); 3621 } 3622 #endif 3623 } 3624 /* Edge vertices have 2 + faces supports */ 3625 for (e = eStart; e < eEnd; ++e) { 3626 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3627 const PetscInt *cone, *support; 3628 PetscInt size, s; 3629 3630 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3631 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3632 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3633 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3634 for (s = 0; s < size; ++s) { 3635 PetscInt r; 3636 3637 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3638 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 3639 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 3640 } 3641 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3642 #if 1 3643 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3644 for (p = 0; p < 2+size; ++p) { 3645 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); 3646 } 3647 #endif 3648 } 3649 /* Face vertices have 4 + cells supports */ 3650 for (f = fStart; f < fEnd; ++f) { 3651 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 3652 const PetscInt *cone, *support; 3653 PetscInt size, s; 3654 3655 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3656 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3657 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (e - eStart)*2 + (f - fStart)*4 + r; 3658 for (s = 0; s < size; ++s) { 3659 PetscInt r; 3660 3661 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3662 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 3663 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 3664 } 3665 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3666 #if 1 3667 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3668 for (p = 0; p < 4+size; ++p) { 3669 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); 3670 } 3671 #endif 3672 } 3673 /* Cell vertices have 6 supports */ 3674 for (c = cStart; c < cEnd; ++c) { 3675 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 3676 PetscInt supportNew[6]; 3677 3678 for (r = 0; r < 6; ++r) { 3679 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 3680 } 3681 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3682 } 3683 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3684 break; 3685 default: 3686 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 3687 } 3688 PetscFunctionReturn(0); 3689 } 3690 3691 #undef __FUNCT__ 3692 #define __FUNCT__ "CellRefinerSetCoordinates" 3693 PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 3694 { 3695 PetscSection coordSection, coordSectionNew; 3696 Vec coordinates, coordinatesNew; 3697 PetscScalar *coords, *coordsNew; 3698 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 3699 PetscInt dim, depth, coordSizeNew, cStart, cEnd, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 3700 PetscErrorCode ierr; 3701 3702 PetscFunctionBegin; 3703 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 3704 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3705 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 3706 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 3707 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 3708 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 3709 ierr = DMPlexGetHybridBounds(dm, NULL, &fMax, &eMax, NULL);CHKERRQ(ierr); 3710 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);} 3711 ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr); 3712 ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 3713 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 3714 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 3715 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dim);CHKERRQ(ierr); 3716 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 3717 if (fMax < 0) fMax = fEnd; 3718 if (eMax < 0) eMax = eEnd; 3719 /* All vertices have the dim coordinates */ 3720 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 3721 ierr = PetscSectionSetDof(coordSectionNew, v, dim);CHKERRQ(ierr); 3722 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dim);CHKERRQ(ierr); 3723 } 3724 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 3725 ierr = DMPlexSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr); 3726 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 3727 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 3728 ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr); 3729 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 3730 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 3731 ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr); 3732 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 3733 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 3734 switch (refiner) { 3735 case 0: break; 3736 case 6: /* Hex 3D */ 3737 /* Face vertices have the average of corner coordinates */ 3738 for (f = fStart; f < fEnd; ++f) { 3739 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 3740 PetscInt *cone = NULL; 3741 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 3742 3743 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3744 for (p = 0; p < closureSize*2; p += 2) { 3745 const PetscInt point = cone[p]; 3746 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 3747 } 3748 for (v = 0; v < coneSize; ++v) { 3749 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 3750 } 3751 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3752 for (d = 0; d < dim; ++d) { 3753 coordsNew[offnew+d] = 0.0; 3754 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 3755 coordsNew[offnew+d] /= coneSize; 3756 } 3757 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3758 } 3759 case 2: /* Hex 2D */ 3760 /* Cell vertices have the average of corner coordinates */ 3761 for (c = cStart; c < cEnd; ++c) { 3762 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (c - cStart) + (dim > 2 ? (fEnd - fStart) : 0); 3763 PetscInt *cone = NULL; 3764 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 3765 3766 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3767 for (p = 0; p < closureSize*2; p += 2) { 3768 const PetscInt point = cone[p]; 3769 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 3770 } 3771 for (v = 0; v < coneSize; ++v) { 3772 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 3773 } 3774 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3775 for (d = 0; d < dim; ++d) { 3776 coordsNew[offnew+d] = 0.0; 3777 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 3778 coordsNew[offnew+d] /= coneSize; 3779 } 3780 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3781 } 3782 case 1: /* Simplicial 2D */ 3783 case 3: /* Hybrid Simplicial 2D */ 3784 case 5: /* Simplicial 3D */ 3785 case 7: /* Hybrid Simplicial 3D */ 3786 /* Edge vertices have the average of endpoint coordinates */ 3787 for (e = eStart; e < eMax; ++e) { 3788 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3789 const PetscInt *cone; 3790 PetscInt coneSize, offA, offB, offnew, d; 3791 3792 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 3793 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 3794 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3795 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 3796 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 3797 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3798 for (d = 0; d < dim; ++d) { 3799 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]); 3800 } 3801 } 3802 /* Old vertices have the same coordinates */ 3803 for (v = vStart; v < vEnd; ++v) { 3804 const PetscInt newv = vStartNew + (v - vStart); 3805 PetscInt off, offnew, d; 3806 3807 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 3808 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3809 for (d = 0; d < dim; ++d) { 3810 coordsNew[offnew+d] = coords[off+d]; 3811 } 3812 } 3813 break; 3814 default: 3815 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 3816 } 3817 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 3818 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 3819 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 3820 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 3821 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 3822 PetscFunctionReturn(0); 3823 } 3824 3825 #undef __FUNCT__ 3826 #define __FUNCT__ "DMPlexCreateProcessSF" 3827 PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 3828 { 3829 PetscInt numRoots, numLeaves, l; 3830 const PetscInt *localPoints; 3831 const PetscSFNode *remotePoints; 3832 PetscInt *localPointsNew; 3833 PetscSFNode *remotePointsNew; 3834 PetscInt *ranks, *ranksNew; 3835 PetscErrorCode ierr; 3836 3837 PetscFunctionBegin; 3838 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 3839 ierr = PetscMalloc(numLeaves * sizeof(PetscInt), &ranks);CHKERRQ(ierr); 3840 for (l = 0; l < numLeaves; ++l) { 3841 ranks[l] = remotePoints[l].rank; 3842 } 3843 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 3844 ierr = PetscMalloc(numLeaves * sizeof(PetscInt), &ranksNew);CHKERRQ(ierr); 3845 ierr = PetscMalloc(numLeaves * sizeof(PetscInt), &localPointsNew);CHKERRQ(ierr); 3846 ierr = PetscMalloc(numLeaves * sizeof(PetscSFNode), &remotePointsNew);CHKERRQ(ierr); 3847 for (l = 0; l < numLeaves; ++l) { 3848 ranksNew[l] = ranks[l]; 3849 localPointsNew[l] = l; 3850 remotePointsNew[l].index = 0; 3851 remotePointsNew[l].rank = ranksNew[l]; 3852 } 3853 ierr = PetscFree(ranks);CHKERRQ(ierr); 3854 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr); 3855 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 3856 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 3857 ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 3858 PetscFunctionReturn(0); 3859 } 3860 3861 #undef __FUNCT__ 3862 #define __FUNCT__ "CellRefinerCreateSF" 3863 PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 3864 { 3865 PetscSF sf, sfNew, sfProcess; 3866 IS processRanks; 3867 MPI_Datatype depthType; 3868 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 3869 const PetscInt *localPoints, *neighbors; 3870 const PetscSFNode *remotePoints; 3871 PetscInt *localPointsNew; 3872 PetscSFNode *remotePointsNew; 3873 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 3874 PetscInt depth, numNeighbors, pStartNew, pEndNew, cStart, cStartNew = 0, cEnd, cMax, vStart, vStartNew = 0, vEnd, vMax, fStart, fStartNew = 0, fEnd, fMax, eStart, eStartNew = 0, eEnd, eMax, r, n; 3875 PetscErrorCode ierr; 3876 3877 PetscFunctionBegin; 3878 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 3879 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3880 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 3881 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 3882 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 3883 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 3884 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 3885 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 3886 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 3887 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 3888 /* Caculate size of new SF */ 3889 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 3890 if (numRoots < 0) PetscFunctionReturn(0); 3891 for (l = 0; l < numLeaves; ++l) { 3892 const PetscInt p = localPoints[l]; 3893 3894 switch (refiner) { 3895 case 1: 3896 /* Simplicial 2D */ 3897 if ((p >= vStart) && (p < vEnd)) { 3898 /* Old vertices stay the same */ 3899 ++numLeavesNew; 3900 } else if ((p >= fStart) && (p < fEnd)) { 3901 /* Old faces add new faces and vertex */ 3902 numLeavesNew += 2 + 1; 3903 } else if ((p >= cStart) && (p < cEnd)) { 3904 /* Old cells add new cells and interior faces */ 3905 numLeavesNew += 4 + 3; 3906 } 3907 break; 3908 case 2: 3909 /* Hex 2D */ 3910 if ((p >= vStart) && (p < vEnd)) { 3911 /* Old vertices stay the same */ 3912 ++numLeavesNew; 3913 } else if ((p >= fStart) && (p < fEnd)) { 3914 /* Old faces add new faces and vertex */ 3915 numLeavesNew += 2 + 1; 3916 } else if ((p >= cStart) && (p < cEnd)) { 3917 /* Old cells add new cells, interior faces, and vertex */ 3918 numLeavesNew += 4 + 4 + 1; 3919 } 3920 break; 3921 case 5: 3922 /* Simplicial 3D */ 3923 if ((p >= vStart) && (p < vEnd)) { 3924 /* Old vertices stay the same */ 3925 ++numLeavesNew; 3926 } else if ((p >= eStart) && (p < eEnd)) { 3927 /* Old edges add new edges and vertex */ 3928 numLeavesNew += 2 + 1; 3929 } else if ((p >= fStart) && (p < fEnd)) { 3930 /* Old faces add new faces and face edges */ 3931 numLeavesNew += 4 + 3; 3932 } else if ((p >= cStart) && (p < cEnd)) { 3933 /* Old cells add new cells and interior faces and edges */ 3934 numLeavesNew += 8 + 8 + 1; 3935 } 3936 break; 3937 case 7: 3938 /* Hybrid Simplicial 3D */ 3939 if ((p >= vStart) && (p < vEnd)) { 3940 /* Interior vertices stay the same */ 3941 ++numLeavesNew; 3942 } else if ((p >= eStart) && (p < eMax)) { 3943 /* Interior edges add new edges and vertex */ 3944 numLeavesNew += 2 + 1; 3945 } else if ((p >= eMax) && (p < eEnd)) { 3946 /* Hybrid edges stay the same */ 3947 ++numLeavesNew; 3948 } else if ((p >= fStart) && (p < fMax)) { 3949 /* Interior faces add new faces and edges */ 3950 numLeavesNew += 4 + 3; 3951 } else if ((p >= fMax) && (p < fEnd)) { 3952 /* Hybrid faces add new faces and edges */ 3953 numLeavesNew += 2 + 1; 3954 } else if ((p >= cStart) && (p < cMax)) { 3955 /* Interior cells add new cells, faces, and edges */ 3956 numLeavesNew += 8 + 8 + 1; 3957 } else if ((p >= cMax) && (p < cEnd)) { 3958 /* Hybrid cells add new cells and faces */ 3959 numLeavesNew += 4 + 3; 3960 } 3961 break; 3962 case 6: 3963 /* Hex 3D */ 3964 if ((p >= vStart) && (p < vEnd)) { 3965 /* Old vertices stay the same */ 3966 ++numLeavesNew; 3967 } else if ((p >= eStart) && (p < eEnd)) { 3968 /* Old edges add new edges, and vertex */ 3969 numLeavesNew += 2 + 1; 3970 } else if ((p >= fStart) && (p < fEnd)) { 3971 /* Old faces add new faces, edges, and vertex */ 3972 numLeavesNew += 4 + 4 + 1; 3973 } else if ((p >= cStart) && (p < cEnd)) { 3974 /* Old cells add new cells, faces, edges, and vertex */ 3975 numLeavesNew += 8 + 12 + 6 + 1; 3976 } 3977 break; 3978 default: 3979 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 3980 } 3981 } 3982 /* Communicate depthSizes for each remote rank */ 3983 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 3984 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 3985 ierr = PetscMalloc5((depth+1)*numNeighbors,PetscInt,&rdepthSize,numNeighbors,PetscInt,&rvStartNew,numNeighbors,PetscInt,&reStartNew,numNeighbors,PetscInt,&rfStartNew,numNeighbors,PetscInt,&rcStartNew);CHKERRQ(ierr); 3986 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); 3987 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 3988 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 3989 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 3990 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 3991 for (n = 0; n < numNeighbors; ++n) { 3992 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 3993 } 3994 depthSizeOld[depth] = cMax; 3995 depthSizeOld[0] = vMax; 3996 depthSizeOld[depth-1] = fMax; 3997 depthSizeOld[1] = eMax; 3998 3999 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 4000 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 4001 4002 depthSizeOld[depth] = cEnd - cStart; 4003 depthSizeOld[0] = vEnd - vStart; 4004 depthSizeOld[depth-1] = fEnd - fStart; 4005 depthSizeOld[1] = eEnd - eStart; 4006 4007 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 4008 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 4009 for (n = 0; n < numNeighbors; ++n) { 4010 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 4011 } 4012 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 4013 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 4014 /* Calculate new point SF */ 4015 ierr = PetscMalloc(numLeavesNew * sizeof(PetscInt), &localPointsNew);CHKERRQ(ierr); 4016 ierr = PetscMalloc(numLeavesNew * sizeof(PetscSFNode), &remotePointsNew);CHKERRQ(ierr); 4017 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 4018 for (l = 0, m = 0; l < numLeaves; ++l) { 4019 PetscInt p = localPoints[l]; 4020 PetscInt rp = remotePoints[l].index, n; 4021 PetscMPIInt rrank = remotePoints[l].rank; 4022 4023 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 4024 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 4025 switch (refiner) { 4026 case 1: 4027 /* Simplicial 2D */ 4028 if ((p >= vStart) && (p < vEnd)) { 4029 /* Old vertices stay the same */ 4030 localPointsNew[m] = vStartNew + (p - vStart); 4031 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4032 remotePointsNew[m].rank = rrank; 4033 ++m; 4034 } else if ((p >= fStart) && (p < fEnd)) { 4035 /* Old faces add new faces and vertex */ 4036 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 4037 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 4038 remotePointsNew[m].rank = rrank; 4039 ++m; 4040 for (r = 0; r < 2; ++r, ++m) { 4041 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 4042 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 4043 remotePointsNew[m].rank = rrank; 4044 } 4045 } else if ((p >= cStart) && (p < cEnd)) { 4046 /* Old cells add new cells and interior faces */ 4047 for (r = 0; r < 4; ++r, ++m) { 4048 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4049 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4050 remotePointsNew[m].rank = rrank; 4051 } 4052 for (r = 0; r < 3; ++r, ++m) { 4053 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 4054 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 4055 remotePointsNew[m].rank = rrank; 4056 } 4057 } 4058 break; 4059 case 2: 4060 /* Hex 2D */ 4061 if ((p >= vStart) && (p < vEnd)) { 4062 /* Old vertices stay the same */ 4063 localPointsNew[m] = vStartNew + (p - vStart); 4064 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4065 remotePointsNew[m].rank = rrank; 4066 ++m; 4067 } else if ((p >= fStart) && (p < fEnd)) { 4068 /* Old faces add new faces and vertex */ 4069 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 4070 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 4071 remotePointsNew[m].rank = rrank; 4072 ++m; 4073 for (r = 0; r < 2; ++r, ++m) { 4074 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 4075 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 4076 remotePointsNew[m].rank = rrank; 4077 } 4078 } else if ((p >= cStart) && (p < cEnd)) { 4079 /* Old cells add new cells, interior faces, and vertex */ 4080 for (r = 0; r < 4; ++r, ++m) { 4081 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4082 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4083 remotePointsNew[m].rank = rrank; 4084 } 4085 for (r = 0; r < 4; ++r, ++m) { 4086 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 4087 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r; 4088 remotePointsNew[m].rank = rrank; 4089 } 4090 for (r = 0; r < 1; ++r, ++m) { 4091 localPointsNew[m] = vStartNew + (fEnd - fStart) + (p - cStart) + r; 4092 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 4093 remotePointsNew[m].rank = rrank; 4094 } 4095 } 4096 break; 4097 case 3: 4098 /* Hybrid simplicial 2D */ 4099 if ((p >= vStart) && (p < vEnd)) { 4100 /* Old vertices stay the same */ 4101 localPointsNew[m] = vStartNew + (p - vStart); 4102 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4103 remotePointsNew[m].rank = rrank; 4104 ++m; 4105 } else if ((p >= fStart) && (p < fMax)) { 4106 /* Old interior faces add new faces and vertex */ 4107 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 4108 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 4109 remotePointsNew[m].rank = rrank; 4110 ++m; 4111 for (r = 0; r < 2; ++r, ++m) { 4112 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 4113 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 4114 remotePointsNew[m].rank = rrank; 4115 } 4116 } else if ((p >= fMax) && (p < fEnd)) { 4117 /* Old hybrid faces stay the same */ 4118 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 4119 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 4120 remotePointsNew[m].rank = rrank; 4121 ++m; 4122 } else if ((p >= cStart) && (p < cMax)) { 4123 /* Old interior cells add new cells and interior faces */ 4124 for (r = 0; r < 4; ++r, ++m) { 4125 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4126 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4127 remotePointsNew[m].rank = rrank; 4128 } 4129 for (r = 0; r < 3; ++r, ++m) { 4130 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 4131 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 4132 remotePointsNew[m].rank = rrank; 4133 } 4134 } else if ((p >= cStart) && (p < cMax)) { 4135 /* Old hybrid cells add new cells and hybrid face */ 4136 for (r = 0; r < 2; ++r, ++m) { 4137 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4138 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4139 remotePointsNew[m].rank = rrank; 4140 } 4141 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 4142 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]); 4143 remotePointsNew[m].rank = rrank; 4144 ++m; 4145 } 4146 break; 4147 case 5: 4148 /* Simplicial 3D */ 4149 if ((p >= vStart) && (p < vEnd)) { 4150 /* Old vertices stay the same */ 4151 localPointsNew[m] = vStartNew + (p - vStart); 4152 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4153 remotePointsNew[m].rank = rrank; 4154 ++m; 4155 } else if ((p >= eStart) && (p < eEnd)) { 4156 /* Old edges add new edges and vertex */ 4157 for (r = 0; r < 2; ++r, ++m) { 4158 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 4159 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 4160 remotePointsNew[m].rank = rrank; 4161 } 4162 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 4163 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 4164 remotePointsNew[m].rank = rrank; 4165 ++m; 4166 } else if ((p >= fStart) && (p < fEnd)) { 4167 /* Old faces add new faces and face edges */ 4168 for (r = 0; r < 4; ++r, ++m) { 4169 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 4170 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 4171 remotePointsNew[m].rank = rrank; 4172 } 4173 for (r = 0; r < 3; ++r, ++m) { 4174 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 4175 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*3 + r; 4176 remotePointsNew[m].rank = rrank; 4177 } 4178 } else if ((p >= cStart) && (p < cEnd)) { 4179 /* Old cells add new cells and interior faces and edges */ 4180 for (r = 0; r < 8; ++r, ++m) { 4181 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 4182 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 4183 remotePointsNew[m].rank = rrank; 4184 } 4185 for (r = 0; r < 8; ++r, ++m) { 4186 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 4187 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*8 + r; 4188 remotePointsNew[m].rank = rrank; 4189 } 4190 for (r = 0; r < 1; ++r, ++m) { 4191 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 4192 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*1 + r; 4193 remotePointsNew[m].rank = rrank; 4194 } 4195 } 4196 break; 4197 case 7: 4198 /* Hybrid Simplicial 3D */ 4199 if ((p >= vStart) && (p < vEnd)) { 4200 /* Interior vertices stay the same */ 4201 localPointsNew[m] = vStartNew + (p - vStart); 4202 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4203 remotePointsNew[m].rank = rrank; 4204 ++m; 4205 } else if ((p >= eStart) && (p < eMax)) { 4206 /* Interior edges add new edges and vertex */ 4207 for (r = 0; r < 2; ++r, ++m) { 4208 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 4209 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 4210 remotePointsNew[m].rank = rrank; 4211 } 4212 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 4213 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 4214 remotePointsNew[m].rank = rrank; 4215 ++m; 4216 } else if ((p >= eMax) && (p < eEnd)) { 4217 /* Hybrid edges stay the same */ 4218 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 4219 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]); 4220 remotePointsNew[m].rank = rrank; 4221 ++m; 4222 } else if ((p >= fStart) && (p < fMax)) { 4223 /* Interior faces add new faces and edges */ 4224 for (r = 0; r < 4; ++r, ++m) { 4225 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 4226 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 4227 remotePointsNew[m].rank = rrank; 4228 } 4229 for (r = 0; r < 3; ++r, ++m) { 4230 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 4231 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 4232 remotePointsNew[m].rank = rrank; 4233 } 4234 } else if ((p >= fMax) && (p < fEnd)) { 4235 /* Hybrid faces add new faces and edges */ 4236 for (r = 0; r < 2; ++r, ++m) { 4237 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fStart)*2 + r; 4238 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; 4239 remotePointsNew[m].rank = rrank; 4240 } 4241 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart) + (cMax - cStart) + (fEnd - fMax); 4242 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]); 4243 remotePointsNew[m].rank = rrank; 4244 } else if ((p >= cStart) && (p < cMax)) { 4245 /* Interior cells add new cells, faces, and edges */ 4246 for (r = 0; r < 8; ++r, ++m) { 4247 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 4248 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 4249 remotePointsNew[m].rank = rrank; 4250 } 4251 for (r = 0; r < 8; ++r, ++m) { 4252 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 4253 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 4254 remotePointsNew[m].rank = rrank; 4255 } 4256 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + r; 4257 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; 4258 remotePointsNew[m].rank = rrank; 4259 } else if ((p >= cMax) && (p < cEnd)) { 4260 /* Hybrid cells add new cells and faces */ 4261 for (r = 0; r < 4; ++r, ++m) { 4262 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 4263 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 4264 remotePointsNew[m].rank = rrank; 4265 } 4266 for (r = 0; r < 3; ++r, ++m) { 4267 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*4 + (p - cMax)*3 + r; 4268 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; 4269 remotePointsNew[m].rank = rrank; 4270 } 4271 } 4272 break; 4273 case 6: 4274 /* Hex 3D */ 4275 if ((p >= vStart) && (p < vEnd)) { 4276 /* Old vertices stay the same */ 4277 localPointsNew[m] = vStartNew + (p - vStart); 4278 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4279 remotePointsNew[m].rank = rrank; 4280 ++m; 4281 } else if ((p >= eStart) && (p < eEnd)) { 4282 /* Old edges add new edges and vertex */ 4283 for (r = 0; r < 2; ++r, ++m) { 4284 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 4285 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 4286 remotePointsNew[m].rank = rrank; 4287 } 4288 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 4289 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 4290 remotePointsNew[m].rank = rrank; 4291 ++m; 4292 } else if ((p >= fStart) && (p < fEnd)) { 4293 /* Old faces add new faces, edges, and vertex */ 4294 for (r = 0; r < 4; ++r, ++m) { 4295 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 4296 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 4297 remotePointsNew[m].rank = rrank; 4298 } 4299 for (r = 0; r < 4; ++r, ++m) { 4300 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 4301 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*4 + r; 4302 remotePointsNew[m].rank = rrank; 4303 } 4304 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 4305 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]); 4306 remotePointsNew[m].rank = rrank; 4307 ++m; 4308 } else if ((p >= cStart) && (p < cEnd)) { 4309 /* Old cells add new cells, faces, edges, and vertex */ 4310 for (r = 0; r < 8; ++r, ++m) { 4311 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 4312 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 4313 remotePointsNew[m].rank = rrank; 4314 } 4315 for (r = 0; r < 12; ++r, ++m) { 4316 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 4317 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*12 + r; 4318 remotePointsNew[m].rank = rrank; 4319 } 4320 for (r = 0; r < 6; ++r, ++m) { 4321 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 4322 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*6 + r; 4323 remotePointsNew[m].rank = rrank; 4324 } 4325 for (r = 0; r < 1; ++r, ++m) { 4326 localPointsNew[m] = vStartNew + (eEnd - eStart) + (fEnd - fStart) + (p - cStart) + r; 4327 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 4328 remotePointsNew[m].rank = rrank; 4329 } 4330 } 4331 break; 4332 default: 4333 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 4334 } 4335 } 4336 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 4337 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 4338 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 4339 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 4340 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 4341 PetscFunctionReturn(0); 4342 } 4343 4344 #undef __FUNCT__ 4345 #define __FUNCT__ "CellRefinerCreateLabels" 4346 PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 4347 { 4348 PetscInt numLabels, l; 4349 PetscInt depth, newp, cStart, cStartNew = 0, cEnd, cMax, vStart, vStartNew = 0, vEnd, vMax, fStart, fStartNew = 0, fEnd, fMax, eStart, eStartNew = 0, eEnd, eMax, r; 4350 PetscErrorCode ierr; 4351 4352 PetscFunctionBegin; 4353 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 4354 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 4355 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 4356 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 4357 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 4358 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 4359 ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 4360 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 4361 switch (refiner) { 4362 case 0: break; 4363 case 7: 4364 case 8: 4365 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 4366 case 3: 4367 case 4: 4368 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 4369 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 4370 } 4371 for (l = 0; l < numLabels; ++l) { 4372 DMLabel label, labelNew; 4373 const char *lname; 4374 PetscBool isDepth; 4375 IS valueIS; 4376 const PetscInt *values; 4377 PetscInt numValues, val; 4378 4379 ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr); 4380 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 4381 if (isDepth) continue; 4382 ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr); 4383 ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr); 4384 ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 4385 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 4386 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 4387 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 4388 for (val = 0; val < numValues; ++val) { 4389 IS pointIS; 4390 const PetscInt *points; 4391 PetscInt numPoints, n; 4392 4393 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 4394 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 4395 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 4396 for (n = 0; n < numPoints; ++n) { 4397 const PetscInt p = points[n]; 4398 switch (refiner) { 4399 case 1: 4400 /* Simplicial 2D */ 4401 if ((p >= vStart) && (p < vEnd)) { 4402 /* Old vertices stay the same */ 4403 newp = vStartNew + (p - vStart); 4404 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4405 } else if ((p >= fStart) && (p < fEnd)) { 4406 /* Old faces add new faces and vertex */ 4407 newp = vStartNew + (vEnd - vStart) + (p - fStart); 4408 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4409 for (r = 0; r < 2; ++r) { 4410 newp = fStartNew + (p - fStart)*2 + r; 4411 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4412 } 4413 } else if ((p >= cStart) && (p < cEnd)) { 4414 /* Old cells add new cells and interior faces */ 4415 for (r = 0; r < 4; ++r) { 4416 newp = cStartNew + (p - cStart)*4 + r; 4417 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4418 } 4419 for (r = 0; r < 3; ++r) { 4420 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 4421 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4422 } 4423 } 4424 break; 4425 case 2: 4426 /* Hex 2D */ 4427 if ((p >= vStart) && (p < vEnd)) { 4428 /* Old vertices stay the same */ 4429 newp = vStartNew + (p - vStart); 4430 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4431 } else if ((p >= fStart) && (p < fEnd)) { 4432 /* Old faces add new faces and vertex */ 4433 newp = vStartNew + (vEnd - vStart) + (p - fStart); 4434 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4435 for (r = 0; r < 2; ++r) { 4436 newp = fStartNew + (p - fStart)*2 + r; 4437 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4438 } 4439 } else if ((p >= cStart) && (p < cEnd)) { 4440 /* Old cells add new cells and interior faces and vertex */ 4441 for (r = 0; r < 4; ++r) { 4442 newp = cStartNew + (p - cStart)*4 + r; 4443 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4444 } 4445 for (r = 0; r < 4; ++r) { 4446 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 4447 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4448 } 4449 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 4450 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4451 } 4452 break; 4453 case 3: 4454 /* Hybrid simplicial 2D */ 4455 if ((p >= vStart) && (p < vEnd)) { 4456 /* Old vertices stay the same */ 4457 newp = vStartNew + (p - vStart); 4458 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4459 } else if ((p >= fStart) && (p < fMax)) { 4460 /* Old interior faces add new faces and vertex */ 4461 newp = vStartNew + (vEnd - vStart) + (p - fStart); 4462 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4463 for (r = 0; r < 2; ++r) { 4464 newp = fStartNew + (p - fStart)*2 + r; 4465 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4466 } 4467 } else if ((p >= fMax) && (p < fEnd)) { 4468 /* Old hybrid faces stay the same */ 4469 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 4470 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4471 } else if ((p >= cStart) && (p < cMax)) { 4472 /* Old interior cells add new cells and interior faces */ 4473 for (r = 0; r < 4; ++r) { 4474 newp = cStartNew + (p - cStart)*4 + r; 4475 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4476 } 4477 for (r = 0; r < 3; ++r) { 4478 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 4479 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4480 } 4481 } else if ((p >= cMax) && (p < cEnd)) { 4482 /* Old hybrid cells add new cells and hybrid face */ 4483 for (r = 0; r < 2; ++r) { 4484 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 4485 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4486 } 4487 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 4488 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4489 } 4490 break; 4491 case 5: 4492 /* Simplicial 3D */ 4493 if ((p >= vStart) && (p < vEnd)) { 4494 /* Old vertices stay the same */ 4495 newp = vStartNew + (p - vStart); 4496 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4497 } else if ((p >= eStart) && (p < eEnd)) { 4498 /* Old edges add new edges and vertex */ 4499 for (r = 0; r < 2; ++r) { 4500 newp = eStartNew + (p - eStart)*2 + r; 4501 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4502 } 4503 newp = vStartNew + (vEnd - vStart) + (p - eStart); 4504 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4505 } else if ((p >= fStart) && (p < fEnd)) { 4506 /* Old faces add new faces and edges */ 4507 for (r = 0; r < 4; ++r) { 4508 newp = fStartNew + (p - fStart)*4 + r; 4509 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4510 } 4511 for (r = 0; r < 3; ++r) { 4512 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 4513 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4514 } 4515 } else if ((p >= cStart) && (p < cEnd)) { 4516 /* Old cells add new cells and interior faces and edges */ 4517 for (r = 0; r < 8; ++r) { 4518 newp = cStartNew + (p - cStart)*8 + r; 4519 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4520 } 4521 for (r = 0; r < 8; ++r) { 4522 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 4523 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4524 } 4525 for (r = 0; r < 1; ++r) { 4526 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 4527 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4528 } 4529 } 4530 break; 4531 case 7: 4532 /* Hybrid Simplicial 3D */ 4533 if ((p >= vStart) && (p < vEnd)) { 4534 /* Interior vertices stay the same */ 4535 newp = vStartNew + (p - vStart); 4536 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4537 } else if ((p >= eStart) && (p < eMax)) { 4538 /* Interior edges add new edges and vertex */ 4539 for (r = 0; r < 2; ++r) { 4540 newp = eStartNew + (p - eStart)*2 + r; 4541 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4542 } 4543 newp = vStartNew + (vEnd - vStart) + (p - eStart); 4544 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4545 } else if ((p >= eMax) && (p < eEnd)) { 4546 /* Hybrid edges stay the same */ 4547 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 4548 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4549 } else if ((p >= fStart) && (p < fMax)) { 4550 /* Interior faces add new faces and edges */ 4551 for (r = 0; r < 4; ++r) { 4552 newp = fStartNew + (p - fStart)*4 + r; 4553 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4554 } 4555 for (r = 0; r < 3; ++r) { 4556 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 4557 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4558 } 4559 } else if ((p >= fMax) && (p < fEnd)) { 4560 /* Hybrid faces add new faces and edges */ 4561 for (r = 0; r < 2; ++r) { 4562 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 4563 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4564 } 4565 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 4566 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4567 } else if ((p >= cStart) && (p < cMax)) { 4568 /* Interior cells add new cells, faces, and edges */ 4569 for (r = 0; r < 8; ++r) { 4570 newp = cStartNew + (p - cStart)*8 + r; 4571 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4572 } 4573 for (r = 0; r < 8; ++r) { 4574 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 4575 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4576 } 4577 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 4578 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4579 } else if ((p >= cMax) && (p < cEnd)) { 4580 /* Hybrid cells add new cells and faces */ 4581 for (r = 0; r < 4; ++r) { 4582 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 4583 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4584 } 4585 for (r = 0; r < 3; ++r) { 4586 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 4587 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4588 } 4589 } 4590 break; 4591 case 6: 4592 /* Hex 3D */ 4593 if ((p >= vStart) && (p < vEnd)) { 4594 /* Old vertices stay the same */ 4595 newp = vStartNew + (p - vStart); 4596 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4597 } else if ((p >= eStart) && (p < eEnd)) { 4598 /* Old edges add new edges and vertex */ 4599 for (r = 0; r < 2; ++r) { 4600 newp = eStartNew + (p - eStart)*2 + r; 4601 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4602 } 4603 newp = vStartNew + (vEnd - vStart) + (p - eStart); 4604 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4605 } else if ((p >= fStart) && (p < fEnd)) { 4606 /* Old faces add new faces, edges, and vertex */ 4607 for (r = 0; r < 4; ++r) { 4608 newp = fStartNew + (p - fStart)*4 + r; 4609 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4610 } 4611 for (r = 0; r < 4; ++r) { 4612 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 4613 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4614 } 4615 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 4616 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4617 } else if ((p >= cStart) && (p < cEnd)) { 4618 /* Old cells add new cells, faces, edges, and vertex */ 4619 for (r = 0; r < 8; ++r) { 4620 newp = cStartNew + (p - cStart)*8 + r; 4621 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4622 } 4623 for (r = 0; r < 12; ++r) { 4624 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 4625 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4626 } 4627 for (r = 0; r < 6; ++r) { 4628 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 4629 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4630 } 4631 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 4632 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4633 } 4634 break; 4635 default: 4636 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 4637 } 4638 } 4639 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 4640 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 4641 } 4642 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 4643 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 4644 if (0) { 4645 ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr); 4646 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 4647 ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 4648 } 4649 } 4650 PetscFunctionReturn(0); 4651 } 4652 4653 #undef __FUNCT__ 4654 #define __FUNCT__ "DMPlexRefineUniform_Internal" 4655 /* This will only work for interpolated meshes */ 4656 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 4657 { 4658 DM rdm; 4659 PetscInt *depthSize; 4660 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 4661 PetscErrorCode ierr; 4662 4663 PetscFunctionBegin; 4664 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 4665 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 4666 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 4667 ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr); 4668 /* Calculate number of new points of each depth */ 4669 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 4670 ierr = PetscMalloc((depth+1) * sizeof(PetscInt), &depthSize);CHKERRQ(ierr); 4671 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 4672 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 4673 /* Step 1: Set chart */ 4674 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 4675 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 4676 /* Step 2: Set cone/support sizes */ 4677 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4678 /* Step 3: Setup refined DM */ 4679 ierr = DMSetUp(rdm);CHKERRQ(ierr); 4680 /* Step 4: Set cones and supports */ 4681 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4682 /* Step 5: Stratify */ 4683 ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 4684 /* Step 6: Set coordinates for vertices */ 4685 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4686 /* Step 7: Create pointSF */ 4687 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4688 /* Step 8: Create labels */ 4689 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4690 ierr = PetscFree(depthSize);CHKERRQ(ierr); 4691 4692 *dmRefined = rdm; 4693 PetscFunctionReturn(0); 4694 } 4695 4696 #undef __FUNCT__ 4697 #define __FUNCT__ "DMPlexSetRefinementUniform" 4698 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 4699 { 4700 DM_Plex *mesh = (DM_Plex*) dm->data; 4701 4702 PetscFunctionBegin; 4703 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4704 mesh->refinementUniform = refinementUniform; 4705 PetscFunctionReturn(0); 4706 } 4707 4708 #undef __FUNCT__ 4709 #define __FUNCT__ "DMPlexGetRefinementUniform" 4710 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 4711 { 4712 DM_Plex *mesh = (DM_Plex*) dm->data; 4713 4714 PetscFunctionBegin; 4715 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4716 PetscValidPointer(refinementUniform, 2); 4717 *refinementUniform = mesh->refinementUniform; 4718 PetscFunctionReturn(0); 4719 } 4720 4721 #undef __FUNCT__ 4722 #define __FUNCT__ "DMPlexSetRefinementLimit" 4723 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 4724 { 4725 DM_Plex *mesh = (DM_Plex*) dm->data; 4726 4727 PetscFunctionBegin; 4728 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4729 mesh->refinementLimit = refinementLimit; 4730 PetscFunctionReturn(0); 4731 } 4732 4733 #undef __FUNCT__ 4734 #define __FUNCT__ "DMPlexGetRefinementLimit" 4735 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 4736 { 4737 DM_Plex *mesh = (DM_Plex*) dm->data; 4738 4739 PetscFunctionBegin; 4740 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4741 PetscValidPointer(refinementLimit, 2); 4742 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 4743 *refinementLimit = mesh->refinementLimit; 4744 PetscFunctionReturn(0); 4745 } 4746 4747 #undef __FUNCT__ 4748 #define __FUNCT__ "DMPlexGetCellRefiner_Internal" 4749 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 4750 { 4751 PetscInt dim, cStart, cEnd, coneSize, cMax; 4752 PetscErrorCode ierr; 4753 4754 PetscFunctionBegin; 4755 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 4756 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 4757 if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);} 4758 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 4759 ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 4760 switch (dim) { 4761 case 2: 4762 switch (coneSize) { 4763 case 3: 4764 if (cMax >= 0) *cellRefiner = 3; /* Hybrid */ 4765 else *cellRefiner = 1; /* Triangular */ 4766 break; 4767 case 4: 4768 if (cMax >= 0) *cellRefiner = 4; /* Hybrid */ 4769 else *cellRefiner = 2; /* Quadrilateral */ 4770 break; 4771 default: 4772 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 4773 } 4774 break; 4775 case 3: 4776 switch (coneSize) { 4777 case 4: 4778 if (cMax >= 0) *cellRefiner = 7; /* Hybrid */ 4779 else *cellRefiner = 5; /* Tetrahedral */ 4780 break; 4781 case 6: 4782 if (cMax >= 0) *cellRefiner = 8; /* Hybrid */ 4783 else *cellRefiner = 6; /* hexahedral */ 4784 break; 4785 default: 4786 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 4787 } 4788 break; 4789 default: 4790 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 4791 } 4792 PetscFunctionReturn(0); 4793 } 4794