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