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 static 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 case 8: 95 /* Hybrid Hex 3D */ 96 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 97 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 98 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 99 /* Hexahedra */ 100 depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */ 101 depthSize[1] = 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart); /* Every edge is split into 2 edge, 4 edges are added for each face, and 6 edges for each cell */ 102 depthSize[2] = 4*(fMax - fStart) + 12*(cMax - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 103 depthSize[3] = 8*(cMax - cStart); /* Every cell split into 8 cells */ 104 /* Quadrilateral Prisms */ 105 depthSize[0] += 0; /* No hybrid vertices */ 106 depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */ 107 depthSize[2] += 2*(fEnd - fMax) + 4*(cEnd - cMax); /* Every hybrid face split into 2 faces and 4 faces are added for each hybrid cell */ 108 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 109 break; 110 default: 111 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 112 } 113 PetscFunctionReturn(0); 114 } 115 116 /* Return triangle edge for orientation o, if it is r for o == 0 */ 117 PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) { 118 return (o < 0 ? 2-(o+r) : o+r)%3; 119 } 120 PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) { 121 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 122 } 123 124 /* Return triangle subface for orientation o, if it is r for o == 0 */ 125 PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) { 126 return (o < 0 ? 3-(o+r) : o+r)%3; 127 } 128 PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) { 129 return (o < 0 ? 3-(o+s) : 3+s-o)%3; 130 } 131 132 /* I HAVE NO IDEA: Return ??? for orientation o, if it is r for o == 0 */ 133 PETSC_STATIC_INLINE PetscInt GetTetSomething_Static(PetscInt o, PetscInt r) { 134 return (o < 0 ? 1-(o+r) : o+r)%3; 135 } 136 PETSC_STATIC_INLINE PetscInt GetTetSomethingInverse_Static(PetscInt o, PetscInt s) { 137 return (o < 0 ? 1-(o+s) : 3+s-o)%3; 138 } 139 140 141 /* Return quad edge for orientation o, if it is r for o == 0 */ 142 PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) { 143 return (o < 0 ? 3-(o+r) : o+r)%4; 144 } 145 PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) { 146 return (o < 0 ? 3-(o+s) : 4+s-o)%4; 147 } 148 149 /* Return quad subface for orientation o, if it is r for o == 0 */ 150 PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) { 151 return (o < 0 ? 4-(o+r) : o+r)%4; 152 } 153 PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) { 154 return (o < 0 ? 4-(o+s) : 4+s-o)%4; 155 } 156 157 #undef __FUNCT__ 158 #define __FUNCT__ "CellRefinerSetConeSizes" 159 static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 160 { 161 PetscInt depth, cStart, cStartNew, cEnd, cMax, c, vStart, vStartNew, vEnd, vMax, v, fStart, fStartNew, fEnd, fMax, f, eStart, eStartNew, eEnd, eMax, e, r; 162 PetscErrorCode ierr; 163 164 PetscFunctionBegin; 165 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 166 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 167 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 168 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 169 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 170 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 171 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 172 switch (refiner) { 173 case 0: break; 174 case 1: 175 /* Simplicial 2D */ 176 /* All cells have 3 faces */ 177 for (c = cStart; c < cEnd; ++c) { 178 for (r = 0; r < 4; ++r) { 179 const PetscInt newp = (c - cStart)*4 + r; 180 181 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 182 } 183 } 184 /* Split faces have 2 vertices and the same cells as the parent */ 185 for (f = fStart; f < fEnd; ++f) { 186 for (r = 0; r < 2; ++r) { 187 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 188 PetscInt size; 189 190 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 191 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 192 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 193 } 194 } 195 /* Interior faces have 2 vertices and 2 cells */ 196 for (c = cStart; c < cEnd; ++c) { 197 for (r = 0; r < 3; ++r) { 198 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 199 200 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 201 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 202 } 203 } 204 /* Old vertices have identical supports */ 205 for (v = vStart; v < vEnd; ++v) { 206 const PetscInt newp = vStartNew + (v - vStart); 207 PetscInt size; 208 209 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 210 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 211 } 212 /* Face vertices have 2 + cells*2 supports */ 213 for (f = fStart; f < fEnd; ++f) { 214 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 215 PetscInt size; 216 217 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 218 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr); 219 } 220 break; 221 case 2: 222 /* Hex 2D */ 223 /* All cells have 4 faces */ 224 for (c = cStart; c < cEnd; ++c) { 225 for (r = 0; r < 4; ++r) { 226 const PetscInt newp = (c - cStart)*4 + r; 227 228 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 229 } 230 } 231 /* Split faces have 2 vertices and the same cells as the parent */ 232 for (f = fStart; f < fEnd; ++f) { 233 for (r = 0; r < 2; ++r) { 234 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 235 PetscInt size; 236 237 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 238 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 239 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 240 } 241 } 242 /* Interior faces have 2 vertices and 2 cells */ 243 for (c = cStart; c < cEnd; ++c) { 244 for (r = 0; r < 4; ++r) { 245 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 246 247 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 248 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 249 } 250 } 251 /* Old vertices have identical supports */ 252 for (v = vStart; v < vEnd; ++v) { 253 const PetscInt newp = vStartNew + (v - vStart); 254 PetscInt size; 255 256 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 257 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 258 } 259 /* Face vertices have 2 + cells supports */ 260 for (f = fStart; f < fEnd; ++f) { 261 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 262 PetscInt size; 263 264 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 265 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 266 } 267 /* Cell vertices have 4 supports */ 268 for (c = cStart; c < cEnd; ++c) { 269 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 270 271 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 272 } 273 break; 274 case 3: 275 /* Hybrid Simplicial 2D */ 276 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 277 cMax = PetscMin(cEnd, cMax); 278 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 279 fMax = PetscMin(fEnd, fMax); 280 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 281 /* Interior cells have 3 faces */ 282 for (c = cStart; c < cMax; ++c) { 283 for (r = 0; r < 4; ++r) { 284 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 285 286 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 287 } 288 } 289 /* Hybrid cells have 4 faces */ 290 for (c = cMax; c < cEnd; ++c) { 291 for (r = 0; r < 2; ++r) { 292 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 293 294 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 295 } 296 } 297 /* Interior split faces have 2 vertices and the same cells as the parent */ 298 for (f = fStart; f < fMax; ++f) { 299 for (r = 0; r < 2; ++r) { 300 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 301 PetscInt size; 302 303 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 304 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 305 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 306 } 307 } 308 /* Interior cell faces have 2 vertices and 2 cells */ 309 for (c = cStart; c < cMax; ++c) { 310 for (r = 0; r < 3; ++r) { 311 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 312 313 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 314 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 315 } 316 } 317 /* Hybrid faces have 2 vertices and the same cells */ 318 for (f = fMax; f < fEnd; ++f) { 319 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 320 PetscInt size; 321 322 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 323 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 324 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 325 } 326 /* Hybrid cell faces have 2 vertices and 2 cells */ 327 for (c = cMax; c < cEnd; ++c) { 328 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 329 330 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 331 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 332 } 333 /* Old vertices have identical supports */ 334 for (v = vStart; v < vEnd; ++v) { 335 const PetscInt newp = vStartNew + (v - vStart); 336 PetscInt size; 337 338 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 339 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 340 } 341 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 342 for (f = fStart; f < fMax; ++f) { 343 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 344 const PetscInt *support; 345 PetscInt size, newSize = 2, s; 346 347 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 348 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 349 for (s = 0; s < size; ++s) { 350 if (support[s] >= cMax) newSize += 1; 351 else newSize += 2; 352 } 353 ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr); 354 } 355 break; 356 case 5: 357 /* Simplicial 3D */ 358 /* All cells have 4 faces */ 359 for (c = cStart; c < cEnd; ++c) { 360 for (r = 0; r < 8; ++r) { 361 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 362 363 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 364 } 365 } 366 /* Split faces have 3 edges and the same cells as the parent */ 367 for (f = fStart; f < fEnd; ++f) { 368 for (r = 0; r < 4; ++r) { 369 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 370 PetscInt size; 371 372 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 373 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 374 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 375 } 376 } 377 /* Interior cell faces have 3 edges and 2 cells */ 378 for (c = cStart; c < cEnd; ++c) { 379 for (r = 0; r < 8; ++r) { 380 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r; 381 382 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 383 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 384 } 385 } 386 /* Split edges have 2 vertices and the same faces */ 387 for (e = eStart; e < eEnd; ++e) { 388 for (r = 0; r < 2; ++r) { 389 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 390 PetscInt size; 391 392 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 393 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 394 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 395 } 396 } 397 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 398 for (f = fStart; f < fEnd; ++f) { 399 for (r = 0; r < 3; ++r) { 400 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 401 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 402 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 403 404 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 405 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 406 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 407 for (s = 0; s < supportSize; ++s) { 408 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 409 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 410 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 411 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 412 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 413 er = GetTetSomethingInverse_Static(ornt[c], r); 414 if (er == eint[c]) { 415 intFaces += 1; 416 } else { 417 intFaces += 2; 418 } 419 } 420 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 421 } 422 } 423 /* Interior cell edges have 2 vertices and 4 faces */ 424 for (c = cStart; c < cEnd; ++c) { 425 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 426 427 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 428 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 429 } 430 /* Old vertices have identical supports */ 431 for (v = vStart; v < vEnd; ++v) { 432 const PetscInt newp = vStartNew + (v - vStart); 433 PetscInt size; 434 435 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 436 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 437 } 438 /* Edge vertices have 2 + faces*2 + cells*0/1 supports */ 439 for (e = eStart; e < eEnd; ++e) { 440 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 441 PetscInt size, *star = NULL, starSize, s, cellSize = 0; 442 443 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 444 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 445 for (s = 0; s < starSize*2; s += 2) { 446 const PetscInt *cone, *ornt; 447 PetscInt e01, e23; 448 449 if ((star[s] >= cStart) && (star[s] < cEnd)) { 450 /* Check edge 0-1 */ 451 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 452 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 453 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 454 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 455 /* Check edge 2-3 */ 456 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 457 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 458 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 459 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 460 if ((e01 == e) || (e23 == e)) ++cellSize; 461 } 462 } 463 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 464 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr); 465 } 466 break; 467 case 7: 468 /* Hybrid Simplicial 3D */ 469 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart), 470 eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 471 /* Interior cells have 4 faces */ 472 for (c = cStart; c < cMax; ++c) { 473 for (r = 0; r < 8; ++r) { 474 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 475 476 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 477 } 478 } 479 /* Hybrid cells have 5 faces */ 480 for (c = cMax; c < cEnd; ++c) { 481 for (r = 0; r < 4; ++r) { 482 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 483 484 ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr); 485 } 486 } 487 /* Interior split faces have 3 edges and the same cells as the parent */ 488 for (f = fStart; f < fMax; ++f) { 489 for (r = 0; r < 4; ++r) { 490 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 491 PetscInt size; 492 493 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 494 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 495 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 496 } 497 } 498 /* Interior cell faces have 3 edges and 2 cells */ 499 for (c = cStart; c < cMax; ++c) { 500 for (r = 0; r < 8; ++r) { 501 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r; 502 503 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 504 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 505 } 506 } 507 /* Hybrid split faces have 4 edges and the same cells as the parent */ 508 for (f = fMax; f < fEnd; ++f) { 509 for (r = 0; r < 2; ++r) { 510 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 511 PetscInt size; 512 513 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 514 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 515 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 516 } 517 } 518 /* Hybrid cells faces have 4 edges and 2 cells */ 519 for (c = cMax; c < cEnd; ++c) { 520 for (r = 0; r < 3; ++r) { 521 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 522 523 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 524 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 525 } 526 } 527 /* Interior split edges have 2 vertices and the same faces */ 528 for (e = eStart; e < eMax; ++e) { 529 for (r = 0; r < 2; ++r) { 530 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 531 PetscInt size; 532 533 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 534 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 535 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 536 } 537 } 538 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 539 for (f = fStart; f < fMax; ++f) { 540 for (r = 0; r < 3; ++r) { 541 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 542 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 543 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 544 545 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 546 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 547 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 548 for (s = 0; s < supportSize; ++s) { 549 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 550 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 551 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 552 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 553 if (support[s] < cMax) { 554 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 555 er = GetTetSomethingInverse_Static(ornt[c], r); 556 if (er == eint[c]) { 557 intFaces += 1; 558 } else { 559 intFaces += 2; 560 } 561 } else { 562 intFaces += 1; 563 } 564 } 565 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 566 } 567 } 568 /* Interior cell edges have 2 vertices and 4 faces */ 569 for (c = cStart; c < cMax; ++c) { 570 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 571 572 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 573 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 574 } 575 /* Hybrid edges have 2 vertices and the same faces */ 576 for (e = eMax; e < eEnd; ++e) { 577 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 578 PetscInt size; 579 580 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 581 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 582 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 583 } 584 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 585 for (f = fMax; f < fEnd; ++f) { 586 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 587 PetscInt size; 588 589 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 590 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 591 ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr); 592 } 593 /* Interior vertices have identical supports */ 594 for (v = vStart; v < vEnd; ++v) { 595 const PetscInt newp = vStartNew + (v - vStart); 596 PetscInt size; 597 598 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 599 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 600 } 601 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 602 for (e = eStart; e < eMax; ++e) { 603 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 604 const PetscInt *support; 605 PetscInt size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0; 606 607 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 608 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 609 for (s = 0; s < size; ++s) { 610 if (support[s] < fMax) faceSize += 2; 611 else faceSize += 1; 612 } 613 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 614 for (s = 0; s < starSize*2; s += 2) { 615 const PetscInt *cone, *ornt; 616 PetscInt e01, e23; 617 618 if ((star[s] >= cStart) && (star[s] < cMax)) { 619 /* Check edge 0-1 */ 620 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 621 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 622 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 623 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 624 /* Check edge 2-3 */ 625 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 626 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 627 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 628 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 629 if ((e01 == e) || (e23 == e)) ++cellSize; 630 } 631 } 632 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 633 ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr); 634 } 635 break; 636 case 6: 637 /* Hex 3D */ 638 /* All cells have 6 faces */ 639 for (c = cStart; c < cEnd; ++c) { 640 for (r = 0; r < 8; ++r) { 641 const PetscInt newp = (c - cStart)*8 + r; 642 643 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 644 } 645 } 646 /* Split faces have 4 edges and the same cells as the parent */ 647 for (f = fStart; f < fEnd; ++f) { 648 for (r = 0; r < 4; ++r) { 649 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 650 PetscInt size; 651 652 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 653 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 654 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 655 } 656 } 657 /* Interior faces have 4 edges and 2 cells */ 658 for (c = cStart; c < cEnd; ++c) { 659 for (r = 0; r < 12; ++r) { 660 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 661 662 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 663 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 664 } 665 } 666 /* Split edges have 2 vertices and the same faces as the parent */ 667 for (e = eStart; e < eEnd; ++e) { 668 for (r = 0; r < 2; ++r) { 669 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 670 PetscInt size; 671 672 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 673 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 674 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 675 } 676 } 677 /* Face edges have 2 vertices and 2+cells faces */ 678 for (f = fStart; f < fEnd; ++f) { 679 for (r = 0; r < 4; ++r) { 680 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 681 PetscInt size; 682 683 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 684 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 685 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 686 } 687 } 688 /* Cell edges have 2 vertices and 4 faces */ 689 for (c = cStart; c < cEnd; ++c) { 690 for (r = 0; r < 6; ++r) { 691 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 692 693 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 694 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 695 } 696 } 697 /* Old vertices have identical supports */ 698 for (v = vStart; v < vEnd; ++v) { 699 const PetscInt newp = vStartNew + (v - vStart); 700 PetscInt size; 701 702 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 703 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 704 } 705 /* Edge vertices have 2 + faces supports */ 706 for (e = eStart; e < eEnd; ++e) { 707 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 708 PetscInt size; 709 710 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 711 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 712 } 713 /* Face vertices have 4 + cells supports */ 714 for (f = fStart; f < fEnd; ++f) { 715 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 716 PetscInt size; 717 718 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 719 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 720 } 721 /* Cell vertices have 6 supports */ 722 for (c = cStart; c < cEnd; ++c) { 723 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 724 725 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 726 } 727 break; 728 case 8: 729 /* Hybrid Hex 3D */ 730 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart), 731 eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 732 /* Interior cells have 6 faces */ 733 for (c = cStart; c < cMax; ++c) { 734 for (r = 0; r < 8; ++r) { 735 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 736 737 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 738 } 739 } 740 /* Hybrid cells have 6 faces */ 741 for (c = cMax; c < cEnd; ++c) { 742 for (r = 0; r < 4; ++r) { 743 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 744 745 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 746 } 747 } 748 /* Interior split faces have 4 edges and the same cells as the parent */ 749 for (f = fStart; f < fMax; ++f) { 750 for (r = 0; r < 4; ++r) { 751 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 752 PetscInt size; 753 754 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 755 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 756 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 757 } 758 } 759 /* Interior cell faces have 4 edges and 2 cells */ 760 for (c = cStart; c < cMax; ++c) { 761 for (r = 0; r < 12; ++r) { 762 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 763 764 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 765 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 766 } 767 } 768 /* Hybrid split faces have 4 edges and the same cells as the parent */ 769 for (f = fMax; f < fEnd; ++f) { 770 for (r = 0; r < 2; ++r) { 771 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 772 PetscInt size; 773 774 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 775 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 776 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 777 } 778 } 779 /* Hybrid cells faces have 4 edges and 2 cells */ 780 for (c = cMax; c < cEnd; ++c) { 781 for (r = 0; r < 4; ++r) { 782 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r; 783 784 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 785 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 786 } 787 } 788 /* Interior split edges have 2 vertices and the same faces as the parent */ 789 for (e = eStart; e < eMax; ++e) { 790 for (r = 0; r < 2; ++r) { 791 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 792 PetscInt size; 793 794 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 795 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 796 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 797 } 798 } 799 /* Interior face edges have 2 vertices and 2+cells faces */ 800 for (f = fStart; f < fMax; ++f) { 801 for (r = 0; r < 4; ++r) { 802 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 803 PetscInt size; 804 805 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 806 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 807 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 808 } 809 } 810 /* Interior cell edges have 2 vertices and 4 faces */ 811 for (c = cStart; c < cMax; ++c) { 812 for (r = 0; r < 6; ++r) { 813 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 814 815 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 816 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 817 } 818 } 819 /* Hybrid edges have 2 vertices and the same faces */ 820 for (e = eMax; e < eEnd; ++e) { 821 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 822 PetscInt size; 823 824 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 825 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 826 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 827 } 828 /* Hybrid face edges have 2 vertices and 2+cells faces */ 829 for (f = fMax; f < fEnd; ++f) { 830 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 831 PetscInt size; 832 833 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 834 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 835 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 836 } 837 /* Hybrid cell edges have 2 vertices and 4 faces */ 838 for (c = cMax; c < cEnd; ++c) { 839 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 840 841 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 842 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 843 } 844 /* Interior vertices have identical supports */ 845 for (v = vStart; v < vEnd; ++v) { 846 const PetscInt newp = vStartNew + (v - vStart); 847 PetscInt size; 848 849 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 850 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 851 } 852 /* Interior edge vertices have 2 + faces supports */ 853 for (e = eStart; e < eMax; ++e) { 854 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 855 PetscInt size; 856 857 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 858 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 859 } 860 /* Interior face vertices have 4 + cells supports */ 861 for (f = fStart; f < fMax; ++f) { 862 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 863 PetscInt size; 864 865 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 866 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 867 } 868 /* Interior cell vertices have 6 supports */ 869 for (c = cStart; c < cMax; ++c) { 870 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 871 872 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 873 } 874 break; 875 default: 876 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 877 } 878 PetscFunctionReturn(0); 879 } 880 881 #undef __FUNCT__ 882 #define __FUNCT__ "CellRefinerSetCones" 883 static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 884 { 885 const PetscInt *faces, cellInd[4] = {0, 1, 2, 3}; 886 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 887 PetscInt cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew, fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew; 888 PetscInt depth, maxSupportSize, *supportRef, c, f, e, v, r, p; 889 PetscErrorCode ierr; 890 891 PetscFunctionBegin; 892 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 893 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 894 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 895 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 896 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 897 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 898 if (refiner) { 899 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 900 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 901 } 902 switch (refiner) { 903 case 0: break; 904 case 1: 905 /* Simplicial 2D */ 906 /* 907 2 908 |\ 909 | \ 910 | \ 911 | \ 912 | C \ 913 | \ 914 | \ 915 2---1---1 916 |\ D / \ 917 | 2 0 \ 918 |A \ / B \ 919 0---0-------1 920 */ 921 /* All cells have 3 faces */ 922 for (c = cStart; c < cEnd; ++c) { 923 const PetscInt newp = cStartNew + (c - cStart)*4; 924 const PetscInt *cone, *ornt; 925 PetscInt coneNew[3], orntNew[3]; 926 927 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 928 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 929 /* A triangle */ 930 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 931 orntNew[0] = ornt[0]; 932 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 933 orntNew[1] = -2; 934 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 935 orntNew[2] = ornt[2]; 936 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 937 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 938 #if 1 939 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); 940 for (p = 0; p < 3; ++p) { 941 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); 942 } 943 #endif 944 /* B triangle */ 945 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 946 orntNew[0] = ornt[0]; 947 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 948 orntNew[1] = ornt[1]; 949 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 950 orntNew[2] = -2; 951 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 952 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 953 #if 1 954 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); 955 for (p = 0; p < 3; ++p) { 956 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); 957 } 958 #endif 959 /* C triangle */ 960 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 961 orntNew[0] = -2; 962 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 963 orntNew[1] = ornt[1]; 964 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 965 orntNew[2] = ornt[2]; 966 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 967 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 968 #if 1 969 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); 970 for (p = 0; p < 3; ++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 /* D triangle */ 975 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 976 orntNew[0] = 0; 977 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 978 orntNew[1] = 0; 979 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 980 orntNew[2] = 0; 981 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 982 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 983 #if 1 984 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); 985 for (p = 0; p < 3; ++p) { 986 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); 987 } 988 #endif 989 } 990 /* Split faces have 2 vertices and the same cells as the parent */ 991 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 992 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 993 for (f = fStart; f < fEnd; ++f) { 994 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 995 996 for (r = 0; r < 2; ++r) { 997 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 998 const PetscInt *cone, *ornt, *support; 999 PetscInt coneNew[2], coneSize, c, supportSize, s; 1000 1001 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1002 coneNew[0] = vStartNew + (cone[0] - vStart); 1003 coneNew[1] = vStartNew + (cone[1] - vStart); 1004 coneNew[(r+1)%2] = newv; 1005 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1006 #if 1 1007 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1008 for (p = 0; p < 2; ++p) { 1009 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); 1010 } 1011 #endif 1012 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1013 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1014 for (s = 0; s < supportSize; ++s) { 1015 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1016 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1017 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1018 for (c = 0; c < coneSize; ++c) { 1019 if (cone[c] == f) break; 1020 } 1021 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1022 } 1023 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1024 #if 1 1025 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1026 for (p = 0; p < supportSize; ++p) { 1027 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); 1028 } 1029 #endif 1030 } 1031 } 1032 /* Interior faces have 2 vertices and 2 cells */ 1033 for (c = cStart; c < cEnd; ++c) { 1034 const PetscInt *cone; 1035 1036 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1037 for (r = 0; r < 3; ++r) { 1038 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 1039 PetscInt coneNew[2]; 1040 PetscInt supportNew[2]; 1041 1042 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1043 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1044 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1045 #if 1 1046 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1047 for (p = 0; p < 2; ++p) { 1048 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); 1049 } 1050 #endif 1051 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1052 supportNew[1] = (c - cStart)*4 + 3; 1053 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1054 #if 1 1055 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1056 for (p = 0; p < 2; ++p) { 1057 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); 1058 } 1059 #endif 1060 } 1061 } 1062 /* Old vertices have identical supports */ 1063 for (v = vStart; v < vEnd; ++v) { 1064 const PetscInt newp = vStartNew + (v - vStart); 1065 const PetscInt *support, *cone; 1066 PetscInt size, s; 1067 1068 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1069 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1070 for (s = 0; s < size; ++s) { 1071 PetscInt r = 0; 1072 1073 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1074 if (cone[1] == v) r = 1; 1075 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1076 } 1077 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1078 #if 1 1079 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1080 for (p = 0; p < size; ++p) { 1081 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); 1082 } 1083 #endif 1084 } 1085 /* Face vertices have 2 + cells*2 supports */ 1086 for (f = fStart; f < fEnd; ++f) { 1087 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1088 const PetscInt *cone, *support; 1089 PetscInt size, s; 1090 1091 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1092 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1093 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1094 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1095 for (s = 0; s < size; ++s) { 1096 PetscInt r = 0; 1097 1098 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1099 if (cone[1] == f) r = 1; 1100 else if (cone[2] == f) r = 2; 1101 supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1102 supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 1103 } 1104 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1105 #if 1 1106 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1107 for (p = 0; p < 2+size*2; ++p) { 1108 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); 1109 } 1110 #endif 1111 } 1112 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1113 break; 1114 case 2: 1115 /* Hex 2D */ 1116 /* 1117 3---------2---------2 1118 | | | 1119 | D 2 C | 1120 | | | 1121 3----3----0----1----1 1122 | | | 1123 | A 0 B | 1124 | | | 1125 0---------0---------1 1126 */ 1127 /* All cells have 4 faces */ 1128 for (c = cStart; c < cEnd; ++c) { 1129 const PetscInt newp = (c - cStart)*4; 1130 const PetscInt *cone, *ornt; 1131 PetscInt coneNew[4], orntNew[4]; 1132 1133 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1134 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1135 /* A quad */ 1136 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1137 orntNew[0] = ornt[0]; 1138 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1139 orntNew[1] = 0; 1140 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1141 orntNew[2] = -2; 1142 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 1143 orntNew[3] = ornt[3]; 1144 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1145 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1146 #if 1 1147 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); 1148 for (p = 0; p < 4; ++p) { 1149 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); 1150 } 1151 #endif 1152 /* B quad */ 1153 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1154 orntNew[0] = ornt[0]; 1155 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1156 orntNew[1] = ornt[1]; 1157 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1158 orntNew[2] = 0; 1159 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1160 orntNew[3] = -2; 1161 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1162 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1163 #if 1 1164 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); 1165 for (p = 0; p < 4; ++p) { 1166 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); 1167 } 1168 #endif 1169 /* C quad */ 1170 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1171 orntNew[0] = -2; 1172 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1173 orntNew[1] = ornt[1]; 1174 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1175 orntNew[2] = ornt[2]; 1176 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1177 orntNew[3] = 0; 1178 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1179 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1180 #if 1 1181 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); 1182 for (p = 0; p < 4; ++p) { 1183 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); 1184 } 1185 #endif 1186 /* D quad */ 1187 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1188 orntNew[0] = 0; 1189 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1190 orntNew[1] = -2; 1191 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1192 orntNew[2] = ornt[2]; 1193 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 1194 orntNew[3] = ornt[3]; 1195 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1196 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1197 #if 1 1198 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); 1199 for (p = 0; p < 4; ++p) { 1200 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); 1201 } 1202 #endif 1203 } 1204 /* Split faces have 2 vertices and the same cells as the parent */ 1205 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1206 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 1207 for (f = fStart; f < fEnd; ++f) { 1208 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1209 1210 for (r = 0; r < 2; ++r) { 1211 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1212 const PetscInt *cone, *ornt, *support; 1213 PetscInt coneNew[2], coneSize, c, supportSize, s; 1214 1215 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1216 coneNew[0] = vStartNew + (cone[0] - vStart); 1217 coneNew[1] = vStartNew + (cone[1] - vStart); 1218 coneNew[(r+1)%2] = newv; 1219 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1220 #if 1 1221 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1222 for (p = 0; p < 2; ++p) { 1223 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); 1224 } 1225 #endif 1226 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1227 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1228 for (s = 0; s < supportSize; ++s) { 1229 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1230 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1231 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1232 for (c = 0; c < coneSize; ++c) { 1233 if (cone[c] == f) break; 1234 } 1235 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 1236 } 1237 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1238 #if 1 1239 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1240 for (p = 0; p < supportSize; ++p) { 1241 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); 1242 } 1243 #endif 1244 } 1245 } 1246 /* Interior faces have 2 vertices and 2 cells */ 1247 for (c = cStart; c < cEnd; ++c) { 1248 const PetscInt *cone; 1249 PetscInt coneNew[2], supportNew[2]; 1250 1251 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1252 for (r = 0; r < 4; ++r) { 1253 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 1254 1255 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1256 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1257 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1258 #if 1 1259 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1260 for (p = 0; p < 2; ++p) { 1261 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); 1262 } 1263 #endif 1264 supportNew[0] = (c - cStart)*4 + r; 1265 supportNew[1] = (c - cStart)*4 + (r+1)%4; 1266 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1267 #if 1 1268 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1269 for (p = 0; p < 2; ++p) { 1270 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); 1271 } 1272 #endif 1273 } 1274 } 1275 /* Old vertices have identical supports */ 1276 for (v = vStart; v < vEnd; ++v) { 1277 const PetscInt newp = vStartNew + (v - vStart); 1278 const PetscInt *support, *cone; 1279 PetscInt size, s; 1280 1281 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1282 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1283 for (s = 0; s < size; ++s) { 1284 PetscInt r = 0; 1285 1286 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1287 if (cone[1] == v) r = 1; 1288 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1289 } 1290 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1291 #if 1 1292 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1293 for (p = 0; p < size; ++p) { 1294 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); 1295 } 1296 #endif 1297 } 1298 /* Face vertices have 2 + cells supports */ 1299 for (f = fStart; f < fEnd; ++f) { 1300 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1301 const PetscInt *cone, *support; 1302 PetscInt size, s; 1303 1304 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1305 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1306 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1307 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1308 for (s = 0; s < size; ++s) { 1309 PetscInt r = 0; 1310 1311 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1312 if (cone[1] == f) r = 1; 1313 else if (cone[2] == f) r = 2; 1314 else if (cone[3] == f) r = 3; 1315 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r; 1316 } 1317 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1318 #if 1 1319 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1320 for (p = 0; p < 2+size; ++p) { 1321 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); 1322 } 1323 #endif 1324 } 1325 /* Cell vertices have 4 supports */ 1326 for (c = cStart; c < cEnd; ++c) { 1327 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1328 PetscInt supportNew[4]; 1329 1330 for (r = 0; r < 4; ++r) { 1331 supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 1332 } 1333 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1334 } 1335 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1336 break; 1337 case 3: 1338 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1339 cMax = PetscMin(cEnd, cMax); 1340 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1341 fMax = PetscMin(fEnd, fMax); 1342 /* Interior cells have 3 faces */ 1343 for (c = cStart; c < cMax; ++c) { 1344 const PetscInt newp = cStartNew + (c - cStart)*4; 1345 const PetscInt *cone, *ornt; 1346 PetscInt coneNew[3], orntNew[3]; 1347 1348 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1349 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1350 /* A triangle */ 1351 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1352 orntNew[0] = ornt[0]; 1353 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 1354 orntNew[1] = -2; 1355 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1356 orntNew[2] = ornt[2]; 1357 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1358 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1359 #if 1 1360 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); 1361 for (p = 0; p < 3; ++p) { 1362 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); 1363 } 1364 #endif 1365 /* B triangle */ 1366 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1367 orntNew[0] = ornt[0]; 1368 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1369 orntNew[1] = ornt[1]; 1370 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 1371 orntNew[2] = -2; 1372 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1373 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1374 #if 1 1375 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); 1376 for (p = 0; p < 3; ++p) { 1377 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); 1378 } 1379 #endif 1380 /* C triangle */ 1381 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 1382 orntNew[0] = -2; 1383 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1384 orntNew[1] = ornt[1]; 1385 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1386 orntNew[2] = ornt[2]; 1387 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1388 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1389 #if 1 1390 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); 1391 for (p = 0; p < 3; ++p) { 1392 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); 1393 } 1394 #endif 1395 /* D triangle */ 1396 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 1397 orntNew[0] = 0; 1398 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 1399 orntNew[1] = 0; 1400 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 1401 orntNew[2] = 0; 1402 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1403 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1404 #if 1 1405 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); 1406 for (p = 0; p < 3; ++p) { 1407 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); 1408 } 1409 #endif 1410 } 1411 /* 1412 2----3----3 1413 | | 1414 | B | 1415 | | 1416 0----4--- 1 1417 | | 1418 | A | 1419 | | 1420 0----2----1 1421 */ 1422 /* Hybrid cells have 4 faces */ 1423 for (c = cMax; c < cEnd; ++c) { 1424 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 1425 const PetscInt *cone, *ornt; 1426 PetscInt coneNew[4], orntNew[4]; 1427 1428 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1429 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1430 /* A quad */ 1431 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1432 orntNew[0] = ornt[0]; 1433 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1434 orntNew[1] = ornt[1]; 1435 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2] - fMax); 1436 orntNew[2] = 0; 1437 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1438 orntNew[3] = 0; 1439 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1440 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1441 #if 1 1442 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); 1443 for (p = 0; p < 4; ++p) { 1444 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); 1445 } 1446 #endif 1447 /* B quad */ 1448 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1449 orntNew[0] = ornt[0]; 1450 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1451 orntNew[1] = ornt[1]; 1452 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1453 orntNew[2] = 0; 1454 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3] - fMax); 1455 orntNew[3] = 0; 1456 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1457 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1458 #if 1 1459 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); 1460 for (p = 0; p < 4; ++p) { 1461 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); 1462 } 1463 #endif 1464 } 1465 /* Interior split faces have 2 vertices and the same cells as the parent */ 1466 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1467 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 1468 for (f = fStart; f < fMax; ++f) { 1469 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1470 1471 for (r = 0; r < 2; ++r) { 1472 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1473 const PetscInt *cone, *ornt, *support; 1474 PetscInt coneNew[2], coneSize, c, supportSize, s; 1475 1476 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1477 coneNew[0] = vStartNew + (cone[0] - vStart); 1478 coneNew[1] = vStartNew + (cone[1] - vStart); 1479 coneNew[(r+1)%2] = newv; 1480 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1481 #if 1 1482 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1483 for (p = 0; p < 2; ++p) { 1484 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); 1485 } 1486 #endif 1487 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1488 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1489 for (s = 0; s < supportSize; ++s) { 1490 if (support[s] >= cMax) { 1491 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 1492 } else { 1493 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1494 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1495 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1496 for (c = 0; c < coneSize; ++c) { 1497 if (cone[c] == f) break; 1498 } 1499 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1500 } 1501 } 1502 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1503 #if 1 1504 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1505 for (p = 0; p < supportSize; ++p) { 1506 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); 1507 } 1508 #endif 1509 } 1510 } 1511 /* Interior cell faces have 2 vertices and 2 cells */ 1512 for (c = cStart; c < cMax; ++c) { 1513 const PetscInt *cone; 1514 1515 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1516 for (r = 0; r < 3; ++r) { 1517 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 1518 PetscInt coneNew[2]; 1519 PetscInt supportNew[2]; 1520 1521 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1522 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1523 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1524 #if 1 1525 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1526 for (p = 0; p < 2; ++p) { 1527 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); 1528 } 1529 #endif 1530 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1531 supportNew[1] = (c - cStart)*4 + 3; 1532 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1533 #if 1 1534 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1535 for (p = 0; p < 2; ++p) { 1536 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); 1537 } 1538 #endif 1539 } 1540 } 1541 /* Interior hybrid faces have 2 vertices and the same cells */ 1542 for (f = fMax; f < fEnd; ++f) { 1543 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 1544 const PetscInt *cone; 1545 const PetscInt *support; 1546 PetscInt coneNew[2]; 1547 PetscInt supportNew[2]; 1548 PetscInt size, s, r; 1549 1550 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1551 coneNew[0] = vStartNew + (cone[0] - vStart); 1552 coneNew[1] = vStartNew + (cone[1] - vStart); 1553 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1554 #if 1 1555 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1556 for (p = 0; p < 2; ++p) { 1557 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); 1558 } 1559 #endif 1560 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1561 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1562 for (s = 0; s < size; ++s) { 1563 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1564 for (r = 0; r < 2; ++r) { 1565 if (cone[r+2] == f) break; 1566 } 1567 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 1568 } 1569 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1570 #if 1 1571 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1572 for (p = 0; p < size; ++p) { 1573 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); 1574 } 1575 #endif 1576 } 1577 /* Cell hybrid faces have 2 vertices and 2 cells */ 1578 for (c = cMax; c < cEnd; ++c) { 1579 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1580 const PetscInt *cone; 1581 PetscInt coneNew[2]; 1582 PetscInt supportNew[2]; 1583 1584 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1585 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 1586 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 1587 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1588 #if 1 1589 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1590 for (p = 0; p < 2; ++p) { 1591 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); 1592 } 1593 #endif 1594 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 1595 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 1596 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1597 #if 1 1598 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1599 for (p = 0; p < 2; ++p) { 1600 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); 1601 } 1602 #endif 1603 } 1604 /* Old vertices have identical supports */ 1605 for (v = vStart; v < vEnd; ++v) { 1606 const PetscInt newp = vStartNew + (v - vStart); 1607 const PetscInt *support, *cone; 1608 PetscInt size, s; 1609 1610 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1611 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1612 for (s = 0; s < size; ++s) { 1613 if (support[s] >= fMax) { 1614 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax); 1615 } else { 1616 PetscInt r = 0; 1617 1618 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1619 if (cone[1] == v) r = 1; 1620 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1621 } 1622 } 1623 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1624 #if 1 1625 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1626 for (p = 0; p < size; ++p) { 1627 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); 1628 } 1629 #endif 1630 } 1631 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 1632 for (f = fStart; f < fMax; ++f) { 1633 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1634 const PetscInt *cone, *support; 1635 PetscInt size, newSize = 2, s; 1636 1637 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1638 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1639 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1640 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1641 for (s = 0; s < size; ++s) { 1642 PetscInt r = 0; 1643 1644 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1645 if (support[s] >= cMax) { 1646 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax); 1647 1648 newSize += 1; 1649 } else { 1650 if (cone[1] == f) r = 1; 1651 else if (cone[2] == f) r = 2; 1652 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1653 supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r; 1654 1655 newSize += 2; 1656 } 1657 } 1658 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1659 #if 1 1660 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1661 for (p = 0; p < newSize; ++p) { 1662 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); 1663 } 1664 #endif 1665 } 1666 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1667 break; 1668 case 5: 1669 /* Simplicial 3D */ 1670 /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 1671 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 1672 for (c = cStart; c < cEnd; ++c) { 1673 const PetscInt newp = cStartNew + (c - cStart)*8; 1674 const PetscInt *cone, *ornt; 1675 PetscInt coneNew[4], orntNew[4]; 1676 1677 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1678 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1679 /* A tetrahedron: {0, a, c, d} */ 1680 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 1681 orntNew[0] = ornt[0]; 1682 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 1683 orntNew[1] = ornt[1]; 1684 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 1685 orntNew[2] = ornt[2]; 1686 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 1687 orntNew[3] = 0; 1688 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1689 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1690 #if 1 1691 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); 1692 for (p = 0; p < 4; ++p) { 1693 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); 1694 } 1695 #endif 1696 /* B tetrahedron: {a, 1, b, e} */ 1697 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 1698 orntNew[0] = ornt[0]; 1699 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 1700 orntNew[1] = ornt[1]; 1701 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 1702 orntNew[2] = 0; 1703 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 1704 orntNew[3] = ornt[3]; 1705 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1706 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1707 #if 1 1708 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); 1709 for (p = 0; p < 4; ++p) { 1710 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); 1711 } 1712 #endif 1713 /* C tetrahedron: {c, b, 2, f} */ 1714 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 1715 orntNew[0] = ornt[0]; 1716 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 1717 orntNew[1] = 0; 1718 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 1719 orntNew[2] = ornt[2]; 1720 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 1721 orntNew[3] = ornt[3]; 1722 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1723 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1724 #if 1 1725 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); 1726 for (p = 0; p < 4; ++p) { 1727 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); 1728 } 1729 #endif 1730 /* D tetrahedron: {d, e, f, 3} */ 1731 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 1732 orntNew[0] = 0; 1733 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 1734 orntNew[1] = ornt[1]; 1735 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 1736 orntNew[2] = ornt[2]; 1737 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 1738 orntNew[3] = ornt[3]; 1739 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1740 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1741 #if 1 1742 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); 1743 for (p = 0; p < 4; ++p) { 1744 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); 1745 } 1746 #endif 1747 /* A' tetrahedron: {d, a, c, f} */ 1748 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 1749 orntNew[0] = -3; 1750 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 1751 orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0); 1752 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 1753 orntNew[2] = 0; 1754 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 1755 orntNew[3] = 2; 1756 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 1757 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 1758 #if 1 1759 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); 1760 for (p = 0; p < 4; ++p) { 1761 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); 1762 } 1763 #endif 1764 /* B' tetrahedron: {e, b, a, f} */ 1765 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 1766 orntNew[0] = -3; 1767 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 1768 orntNew[1] = 1; 1769 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 1770 orntNew[2] = 0; 1771 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 1772 orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0); 1773 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 1774 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 1775 #if 1 1776 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); 1777 for (p = 0; p < 4; ++p) { 1778 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); 1779 } 1780 #endif 1781 /* C' tetrahedron: {b, f, c, a} */ 1782 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 1783 orntNew[0] = -3; 1784 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 1785 orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2); 1786 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 1787 orntNew[2] = -3; 1788 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 1789 orntNew[3] = -2; 1790 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 1791 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 1792 #if 1 1793 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); 1794 for (p = 0; p < 4; ++p) { 1795 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); 1796 } 1797 #endif 1798 /* D' tetrahedron: {f, e, d, a} */ 1799 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 1800 orntNew[0] = -3; 1801 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 1802 orntNew[1] = -3; 1803 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 1804 orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0); 1805 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 1806 orntNew[3] = -3; 1807 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 1808 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 1809 #if 1 1810 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); 1811 for (p = 0; p < 4; ++p) { 1812 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); 1813 } 1814 #endif 1815 } 1816 /* Split faces have 3 edges and the same cells as the parent */ 1817 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1818 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 1819 for (f = fStart; f < fEnd; ++f) { 1820 const PetscInt newp = fStartNew + (f - fStart)*4; 1821 const PetscInt *cone, *ornt, *support; 1822 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 1823 1824 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1825 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 1826 /* A triangle */ 1827 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 1828 orntNew[0] = ornt[0]; 1829 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 1830 orntNew[1] = -2; 1831 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 1832 orntNew[2] = ornt[2]; 1833 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1834 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1835 #if 1 1836 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); 1837 for (p = 0; p < 3; ++p) { 1838 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 1839 } 1840 #endif 1841 /* B triangle */ 1842 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 1843 orntNew[0] = ornt[0]; 1844 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 1845 orntNew[1] = ornt[1]; 1846 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 1847 orntNew[2] = -2; 1848 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1849 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1850 #if 1 1851 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); 1852 for (p = 0; p < 3; ++p) { 1853 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); 1854 } 1855 #endif 1856 /* C triangle */ 1857 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 1858 orntNew[0] = -2; 1859 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 1860 orntNew[1] = ornt[1]; 1861 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 1862 orntNew[2] = ornt[2]; 1863 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1864 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1865 #if 1 1866 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); 1867 for (p = 0; p < 3; ++p) { 1868 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); 1869 } 1870 #endif 1871 /* D triangle */ 1872 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 1873 orntNew[0] = 0; 1874 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 1875 orntNew[1] = 0; 1876 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 1877 orntNew[2] = 0; 1878 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1879 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1880 #if 1 1881 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); 1882 for (p = 0; p < 3; ++p) { 1883 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); 1884 } 1885 #endif 1886 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1887 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1888 for (r = 0; r < 4; ++r) { 1889 for (s = 0; s < supportSize; ++s) { 1890 PetscInt subf; 1891 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1892 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1893 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1894 for (c = 0; c < coneSize; ++c) { 1895 if (cone[c] == f) break; 1896 } 1897 subf = GetTriSubfaceInverse_Static(ornt[c], r); 1898 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 1899 } 1900 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 1901 #if 1 1902 if ((newp+r < fStartNew) || (newp+r >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+r, fStartNew, fEndNew); 1903 for (p = 0; p < supportSize; ++p) { 1904 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); 1905 } 1906 #endif 1907 } 1908 } 1909 /* Interior faces have 3 edges and 2 cells */ 1910 for (c = cStart; c < cEnd; ++c) { 1911 PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 1912 const PetscInt *cone, *ornt; 1913 PetscInt coneNew[3], orntNew[3]; 1914 PetscInt supportNew[2]; 1915 1916 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1917 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1918 /* Face A: {c, a, d} */ 1919 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 1920 orntNew[0] = ornt[0] < 0 ? -2 : 0; 1921 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 1922 orntNew[1] = ornt[1] < 0 ? -2 : 0; 1923 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2); 1924 orntNew[2] = ornt[2] < 0 ? -2 : 0; 1925 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1926 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1927 #if 1 1928 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1929 for (p = 0; p < 3; ++p) { 1930 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); 1931 } 1932 #endif 1933 supportNew[0] = (c - cStart)*8 + 0; 1934 supportNew[1] = (c - cStart)*8 + 0+4; 1935 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1936 #if 1 1937 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1938 for (p = 0; p < 2; ++p) { 1939 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); 1940 } 1941 #endif 1942 ++newp; 1943 /* Face B: {a, b, e} */ 1944 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 1945 orntNew[0] = ornt[0] < 0 ? -2 : 0; 1946 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0); 1947 orntNew[1] = ornt[3] < 0 ? -2 : 0; 1948 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 1949 orntNew[2] = ornt[1] < 0 ? -2 : 0; 1950 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1951 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1952 #if 1 1953 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1954 for (p = 0; p < 3; ++p) { 1955 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); 1956 } 1957 #endif 1958 supportNew[0] = (c - cStart)*8 + 1; 1959 supportNew[1] = (c - cStart)*8 + 1+4; 1960 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1961 #if 1 1962 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1963 for (p = 0; p < 2; ++p) { 1964 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); 1965 } 1966 #endif 1967 ++newp; 1968 /* Face C: {c, f, b} */ 1969 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 1970 orntNew[0] = ornt[2] < 0 ? -2 : 0; 1971 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 1972 orntNew[1] = ornt[3] < 0 ? -2 : 0; 1973 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1); 1974 orntNew[2] = ornt[0] < 0 ? -2 : 0; 1975 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1976 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1977 #if 1 1978 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1979 for (p = 0; p < 3; ++p) { 1980 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); 1981 } 1982 #endif 1983 supportNew[0] = (c - cStart)*8 + 2; 1984 supportNew[1] = (c - cStart)*8 + 2+4; 1985 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1986 #if 1 1987 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1988 for (p = 0; p < 2; ++p) { 1989 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); 1990 } 1991 #endif 1992 ++newp; 1993 /* Face D: {d, e, f} */ 1994 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0); 1995 orntNew[0] = ornt[1] < 0 ? -2 : 0; 1996 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 1997 orntNew[1] = ornt[3] < 0 ? -2 : 0; 1998 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 1999 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2000 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2001 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2002 #if 1 2003 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2004 for (p = 0; p < 3; ++p) { 2005 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); 2006 } 2007 #endif 2008 supportNew[0] = (c - cStart)*8 + 3; 2009 supportNew[1] = (c - cStart)*8 + 3+4; 2010 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2011 #if 1 2012 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2013 for (p = 0; p < 2; ++p) { 2014 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); 2015 } 2016 #endif 2017 ++newp; 2018 /* Face E: {d, f, a} */ 2019 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 2020 orntNew[0] = ornt[2] < 0 ? 0 : -2; 2021 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2022 orntNew[1] = -2; 2023 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 2024 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2025 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2026 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2027 #if 1 2028 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2029 for (p = 0; p < 3; ++p) { 2030 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); 2031 } 2032 #endif 2033 supportNew[0] = (c - cStart)*8 + 0+4; 2034 supportNew[1] = (c - cStart)*8 + 3+4; 2035 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2036 #if 1 2037 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2038 for (p = 0; p < 2; ++p) { 2039 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); 2040 } 2041 #endif 2042 ++newp; 2043 /* Face F: {c, a, f} */ 2044 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 2045 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2046 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2047 orntNew[1] = 0; 2048 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 2049 orntNew[2] = ornt[2] < 0 ? 0 : -2; 2050 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2051 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2052 #if 1 2053 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2054 for (p = 0; p < 3; ++p) { 2055 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); 2056 } 2057 #endif 2058 supportNew[0] = (c - cStart)*8 + 0+4; 2059 supportNew[1] = (c - cStart)*8 + 2+4; 2060 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2061 #if 1 2062 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2063 for (p = 0; p < 2; ++p) { 2064 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); 2065 } 2066 #endif 2067 ++newp; 2068 /* Face G: {e, a, f} */ 2069 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 2070 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2071 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2072 orntNew[1] = 0; 2073 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 2074 orntNew[2] = ornt[3] < 0 ? 0 : -2; 2075 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2076 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2077 #if 1 2078 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2079 for (p = 0; p < 3; ++p) { 2080 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); 2081 } 2082 #endif 2083 supportNew[0] = (c - cStart)*8 + 1+4; 2084 supportNew[1] = (c - cStart)*8 + 3+4; 2085 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2086 #if 1 2087 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2088 for (p = 0; p < 2; ++p) { 2089 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); 2090 } 2091 #endif 2092 ++newp; 2093 /* Face H: {a, b, f} */ 2094 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 2095 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2096 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 2097 orntNew[1] = ornt[3] < 0 ? 0 : -2; 2098 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2099 orntNew[2] = -2; 2100 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2101 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2102 #if 1 2103 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2104 for (p = 0; p < 3; ++p) { 2105 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); 2106 } 2107 #endif 2108 supportNew[0] = (c - cStart)*8 + 1+4; 2109 supportNew[1] = (c - cStart)*8 + 2+4; 2110 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2111 #if 1 2112 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2113 for (p = 0; p < 2; ++p) { 2114 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); 2115 } 2116 #endif 2117 ++newp; 2118 } 2119 /* Split Edges have 2 vertices and the same faces as the parent */ 2120 for (e = eStart; e < eEnd; ++e) { 2121 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 2122 2123 for (r = 0; r < 2; ++r) { 2124 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 2125 const PetscInt *cone, *ornt, *support; 2126 PetscInt coneNew[2], coneSize, c, supportSize, s; 2127 2128 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 2129 coneNew[0] = vStartNew + (cone[0] - vStart); 2130 coneNew[1] = vStartNew + (cone[1] - vStart); 2131 coneNew[(r+1)%2] = newv; 2132 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2133 #if 1 2134 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2135 for (p = 0; p < 2; ++p) { 2136 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); 2137 } 2138 #endif 2139 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 2140 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2141 for (s = 0; s < supportSize; ++s) { 2142 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2143 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2144 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2145 for (c = 0; c < coneSize; ++c) { 2146 if (cone[c] == e) break; 2147 } 2148 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 2149 } 2150 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2151 #if 1 2152 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2153 for (p = 0; p < supportSize; ++p) { 2154 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); 2155 } 2156 #endif 2157 } 2158 } 2159 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 2160 for (f = fStart; f < fEnd; ++f) { 2161 const PetscInt *cone, *ornt, *support; 2162 PetscInt coneSize, supportSize, s; 2163 2164 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2165 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2166 for (r = 0; r < 3; ++r) { 2167 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 2168 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 2169 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 2170 -1, -1, 1, 6, 0, 4, 2171 2, 5, 3, 4, -1, -1, 2172 -1, -1, 3, 6, 2, 7}; 2173 2174 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2175 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 2176 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 2177 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2178 #if 1 2179 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2180 for (p = 0; p < 2; ++p) { 2181 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); 2182 } 2183 #endif 2184 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 2185 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 2186 for (s = 0; s < supportSize; ++s) { 2187 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2188 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2189 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2190 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 2191 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 2192 er = GetTetSomethingInverse_Static(ornt[c], r); 2193 if (er == eint[c]) { 2194 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 2195 } else { 2196 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 2197 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 2198 } 2199 } 2200 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2201 #if 1 2202 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2203 for (p = 0; p < intFaces; ++p) { 2204 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); 2205 } 2206 #endif 2207 } 2208 } 2209 /* Interior edges have 2 vertices and 4 faces */ 2210 for (c = cStart; c < cEnd; ++c) { 2211 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2212 const PetscInt *cone, *ornt, *fcone; 2213 PetscInt coneNew[2], supportNew[4], find; 2214 2215 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2216 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2217 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 2218 find = GetTriEdge_Static(ornt[0], 0); 2219 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2220 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 2221 find = GetTriEdge_Static(ornt[2], 1); 2222 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2223 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2224 #if 1 2225 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2226 for (p = 0; p < 2; ++p) { 2227 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); 2228 } 2229 #endif 2230 supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2231 supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2232 supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2233 supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2234 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2235 #if 1 2236 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2237 for (p = 0; p < 4; ++p) { 2238 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); 2239 } 2240 #endif 2241 } 2242 /* Old vertices have identical supports */ 2243 for (v = vStart; v < vEnd; ++v) { 2244 const PetscInt newp = vStartNew + (v - vStart); 2245 const PetscInt *support, *cone; 2246 PetscInt size, s; 2247 2248 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2249 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2250 for (s = 0; s < size; ++s) { 2251 PetscInt r = 0; 2252 2253 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2254 if (cone[1] == v) r = 1; 2255 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 2256 } 2257 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2258 #if 1 2259 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2260 for (p = 0; p < size; ++p) { 2261 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); 2262 } 2263 #endif 2264 } 2265 /* Edge vertices have 2 + face*2 + 0/1 supports */ 2266 for (e = eStart; e < eEnd; ++e) { 2267 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 2268 const PetscInt *cone, *support; 2269 PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 2270 2271 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 2272 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2273 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 2274 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 2275 for (s = 0; s < size; ++s) { 2276 PetscInt r = 0; 2277 2278 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2279 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2280 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 2281 supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 2282 supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 2283 } 2284 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2285 for (s = 0; s < starSize*2; s += 2) { 2286 const PetscInt *cone, *ornt; 2287 PetscInt e01, e23; 2288 2289 if ((star[s] >= cStart) && (star[s] < cEnd)) { 2290 /* Check edge 0-1 */ 2291 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2292 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2293 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 2294 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 2295 /* Check edge 2-3 */ 2296 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2297 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2298 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 2299 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 2300 if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 2301 } 2302 } 2303 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2304 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2305 #if 1 2306 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2307 for (p = 0; p < 2+size*2+cellSize; ++p) { 2308 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); 2309 } 2310 #endif 2311 } 2312 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2313 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 2314 break; 2315 case 7: 2316 /* Hybrid Simplicial 3D */ 2317 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 2318 /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 2319 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 2320 for (c = cStart; c < cMax; ++c) { 2321 const PetscInt newp = cStartNew + (c - cStart)*8; 2322 const PetscInt *cone, *ornt; 2323 PetscInt coneNew[4], orntNew[4]; 2324 2325 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2326 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2327 /* A tetrahedron: {0, a, c, d} */ 2328 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 2329 orntNew[0] = ornt[0]; 2330 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 2331 orntNew[1] = ornt[1]; 2332 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 2333 orntNew[2] = ornt[2]; 2334 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 2335 orntNew[3] = 0; 2336 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2337 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2338 #if 1 2339 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); 2340 for (p = 0; p < 4; ++p) { 2341 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); 2342 } 2343 #endif 2344 /* B tetrahedron: {a, 1, b, e} */ 2345 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 2346 orntNew[0] = ornt[0]; 2347 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 2348 orntNew[1] = ornt[1]; 2349 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 2350 orntNew[2] = 0; 2351 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 2352 orntNew[3] = ornt[3]; 2353 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2354 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2355 #if 1 2356 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); 2357 for (p = 0; p < 4; ++p) { 2358 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); 2359 } 2360 #endif 2361 /* C tetrahedron: {c, b, 2, f} */ 2362 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 2363 orntNew[0] = ornt[0]; 2364 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 2365 orntNew[1] = 0; 2366 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 2367 orntNew[2] = ornt[2]; 2368 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 2369 orntNew[3] = ornt[3]; 2370 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2371 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2372 #if 1 2373 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); 2374 for (p = 0; p < 4; ++p) { 2375 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); 2376 } 2377 #endif 2378 /* D tetrahedron: {d, e, f, 3} */ 2379 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 2380 orntNew[0] = 0; 2381 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 2382 orntNew[1] = ornt[1]; 2383 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 2384 orntNew[2] = ornt[2]; 2385 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 2386 orntNew[3] = ornt[3]; 2387 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2388 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2389 #if 1 2390 if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cMaxNew); 2391 for (p = 0; p < 4; ++p) { 2392 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); 2393 } 2394 #endif 2395 /* A' tetrahedron: {d, a, c, f} */ 2396 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 2397 orntNew[0] = -3; 2398 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 2399 orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0); 2400 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 2401 orntNew[2] = 0; 2402 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 2403 orntNew[3] = 2; 2404 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 2405 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 2406 #if 1 2407 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); 2408 for (p = 0; p < 4; ++p) { 2409 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); 2410 } 2411 #endif 2412 /* B' tetrahedron: {e, b, a, f} */ 2413 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 2414 orntNew[0] = -3; 2415 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 2416 orntNew[1] = 1; 2417 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 2418 orntNew[2] = 0; 2419 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 2420 orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0); 2421 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 2422 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 2423 #if 1 2424 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); 2425 for (p = 0; p < 4; ++p) { 2426 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); 2427 } 2428 #endif 2429 /* C' tetrahedron: {b, f, c, a} */ 2430 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 2431 orntNew[0] = -3; 2432 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 2433 orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2); 2434 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 2435 orntNew[2] = -3; 2436 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 2437 orntNew[3] = -2; 2438 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 2439 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 2440 #if 1 2441 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); 2442 for (p = 0; p < 4; ++p) { 2443 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); 2444 } 2445 #endif 2446 /* D' tetrahedron: {f, e, d, a} */ 2447 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 2448 orntNew[0] = -3; 2449 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 2450 orntNew[1] = -3; 2451 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 2452 orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0); 2453 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 2454 orntNew[3] = -3; 2455 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 2456 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 2457 #if 1 2458 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); 2459 for (p = 0; p < 4; ++p) { 2460 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); 2461 } 2462 #endif 2463 } 2464 /* Hybrid cells have 5 faces */ 2465 for (c = cMax; c < cEnd; ++c) { 2466 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4; 2467 const PetscInt *cone, *ornt, *fornt; 2468 PetscInt coneNew[5], orntNew[5]; 2469 2470 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2471 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2472 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 2473 for (r = 0; r < 3; ++r) { 2474 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 2475 orntNew[0] = ornt[0]; 2476 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 2477 orntNew[1] = ornt[1]; 2478 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); 2479 orntNew[2] = 0; 2480 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); 2481 orntNew[3] = 0; 2482 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 2483 orntNew[4] = 0; 2484 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 2485 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 2486 #if 1 2487 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); 2488 for (p = 0; p < 2; ++p) { 2489 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); 2490 } 2491 for (p = 2; p < 5; ++p) { 2492 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); 2493 } 2494 #endif 2495 } 2496 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 2497 orntNew[0] = 0; 2498 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 2499 orntNew[1] = 0; 2500 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 2501 orntNew[2] = 0; 2502 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 2503 orntNew[3] = 0; 2504 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 2505 orntNew[4] = 0; 2506 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2507 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2508 #if 1 2509 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); 2510 for (p = 0; p < 2; ++p) { 2511 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); 2512 } 2513 for (p = 2; p < 5; ++p) { 2514 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); 2515 } 2516 #endif 2517 } 2518 /* Split faces have 3 edges and the same cells as the parent */ 2519 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2520 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 2521 for (f = fStart; f < fMax; ++f) { 2522 const PetscInt newp = fStartNew + (f - fStart)*4; 2523 const PetscInt *cone, *ornt, *support; 2524 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 2525 2526 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2527 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2528 /* A triangle */ 2529 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 2530 orntNew[0] = ornt[0]; 2531 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 2532 orntNew[1] = -2; 2533 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 2534 orntNew[2] = ornt[2]; 2535 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2536 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2537 #if 1 2538 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); 2539 for (p = 0; p < 3; ++p) { 2540 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); 2541 } 2542 #endif 2543 /* B triangle */ 2544 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 2545 orntNew[0] = ornt[0]; 2546 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 2547 orntNew[1] = ornt[1]; 2548 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 2549 orntNew[2] = -2; 2550 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2551 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2552 #if 1 2553 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); 2554 for (p = 0; p < 3; ++p) { 2555 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); 2556 } 2557 #endif 2558 /* C triangle */ 2559 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 2560 orntNew[0] = -2; 2561 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 2562 orntNew[1] = ornt[1]; 2563 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 2564 orntNew[2] = ornt[2]; 2565 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2566 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2567 #if 1 2568 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); 2569 for (p = 0; p < 3; ++p) { 2570 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); 2571 } 2572 #endif 2573 /* D triangle */ 2574 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 2575 orntNew[0] = 0; 2576 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 2577 orntNew[1] = 0; 2578 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 2579 orntNew[2] = 0; 2580 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2581 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2582 #if 1 2583 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); 2584 for (p = 0; p < 3; ++p) { 2585 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); 2586 } 2587 #endif 2588 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2589 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2590 for (r = 0; r < 4; ++r) { 2591 for (s = 0; s < supportSize; ++s) { 2592 PetscInt subf; 2593 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2594 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2595 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2596 for (c = 0; c < coneSize; ++c) { 2597 if (cone[c] == f) break; 2598 } 2599 subf = GetTriSubfaceInverse_Static(ornt[c], r); 2600 if (support[s] < cMax) { 2601 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 2602 } else { 2603 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf); 2604 } 2605 } 2606 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 2607 #if 1 2608 if ((newp+r < fStartNew) || (newp+r >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+r, fStartNew, fMaxNew); 2609 for (p = 0; p < supportSize; ++p) { 2610 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); 2611 } 2612 #endif 2613 } 2614 } 2615 /* Interior cell faces have 3 edges and 2 cells */ 2616 for (c = cStart; c < cMax; ++c) { 2617 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 2618 const PetscInt *cone, *ornt; 2619 PetscInt coneNew[3], orntNew[3]; 2620 PetscInt supportNew[2]; 2621 2622 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2623 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2624 /* Face A: {c, a, d} */ 2625 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 2626 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2627 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 2628 orntNew[1] = ornt[1] < 0 ? -2 : 0; 2629 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2); 2630 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2631 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2632 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2633 #if 1 2634 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2635 for (p = 0; p < 3; ++p) { 2636 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); 2637 } 2638 #endif 2639 supportNew[0] = (c - cStart)*8 + 0; 2640 supportNew[1] = (c - cStart)*8 + 0+4; 2641 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2642 #if 1 2643 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2644 for (p = 0; p < 2; ++p) { 2645 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); 2646 } 2647 #endif 2648 ++newp; 2649 /* Face B: {a, b, e} */ 2650 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 2651 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2652 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0); 2653 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2654 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 2655 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2656 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2657 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2658 #if 1 2659 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); 2660 for (p = 0; p < 3; ++p) { 2661 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); 2662 } 2663 #endif 2664 supportNew[0] = (c - cStart)*8 + 1; 2665 supportNew[1] = (c - cStart)*8 + 1+4; 2666 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2667 #if 1 2668 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2669 for (p = 0; p < 2; ++p) { 2670 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); 2671 } 2672 #endif 2673 ++newp; 2674 /* Face C: {c, f, b} */ 2675 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 2676 orntNew[0] = ornt[2] < 0 ? -2 : 0; 2677 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 2678 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2679 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1); 2680 orntNew[2] = ornt[0] < 0 ? -2 : 0; 2681 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2682 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2683 #if 1 2684 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2685 for (p = 0; p < 3; ++p) { 2686 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); 2687 } 2688 #endif 2689 supportNew[0] = (c - cStart)*8 + 2; 2690 supportNew[1] = (c - cStart)*8 + 2+4; 2691 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2692 #if 1 2693 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2694 for (p = 0; p < 2; ++p) { 2695 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); 2696 } 2697 #endif 2698 ++newp; 2699 /* Face D: {d, e, f} */ 2700 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0); 2701 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2702 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 2703 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2704 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 2705 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2706 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2707 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2708 #if 1 2709 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2710 for (p = 0; p < 3; ++p) { 2711 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); 2712 } 2713 #endif 2714 supportNew[0] = (c - cStart)*8 + 3; 2715 supportNew[1] = (c - cStart)*8 + 3+4; 2716 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2717 #if 1 2718 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2719 for (p = 0; p < 2; ++p) { 2720 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); 2721 } 2722 #endif 2723 ++newp; 2724 /* Face E: {d, f, a} */ 2725 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 2726 orntNew[0] = ornt[2] < 0 ? 0 : -2; 2727 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2728 orntNew[1] = -2; 2729 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 2730 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2731 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2732 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2733 #if 1 2734 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2735 for (p = 0; p < 3; ++p) { 2736 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); 2737 } 2738 #endif 2739 supportNew[0] = (c - cStart)*8 + 0+4; 2740 supportNew[1] = (c - cStart)*8 + 3+4; 2741 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2742 #if 1 2743 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2744 for (p = 0; p < 2; ++p) { 2745 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); 2746 } 2747 #endif 2748 ++newp; 2749 /* Face F: {c, a, f} */ 2750 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 2751 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2752 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2753 orntNew[1] = 0; 2754 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 2755 orntNew[2] = ornt[2] < 0 ? 0 : -2; 2756 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2757 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2758 #if 1 2759 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2760 for (p = 0; p < 3; ++p) { 2761 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); 2762 } 2763 #endif 2764 supportNew[0] = (c - cStart)*8 + 0+4; 2765 supportNew[1] = (c - cStart)*8 + 2+4; 2766 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2767 #if 1 2768 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2769 for (p = 0; p < 2; ++p) { 2770 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); 2771 } 2772 #endif 2773 ++newp; 2774 /* Face G: {e, a, f} */ 2775 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 2776 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2777 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2778 orntNew[1] = 0; 2779 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 2780 orntNew[2] = ornt[3] < 0 ? 0 : -2; 2781 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2782 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2783 #if 1 2784 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2785 for (p = 0; p < 3; ++p) { 2786 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); 2787 } 2788 #endif 2789 supportNew[0] = (c - cStart)*8 + 1+4; 2790 supportNew[1] = (c - cStart)*8 + 3+4; 2791 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2792 #if 1 2793 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2794 for (p = 0; p < 2; ++p) { 2795 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); 2796 } 2797 #endif 2798 ++newp; 2799 /* Face H: {a, b, f} */ 2800 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 2801 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2802 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 2803 orntNew[1] = ornt[3] < 0 ? 0 : -2; 2804 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2805 orntNew[2] = -2; 2806 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2807 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2808 #if 1 2809 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2810 for (p = 0; p < 3; ++p) { 2811 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); 2812 } 2813 #endif 2814 supportNew[0] = (c - cStart)*8 + 1+4; 2815 supportNew[1] = (c - cStart)*8 + 2+4; 2816 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2817 #if 1 2818 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2819 for (p = 0; p < 2; ++p) { 2820 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); 2821 } 2822 #endif 2823 ++newp; 2824 } 2825 /* Hybrid split faces have 4 edges and same cells */ 2826 for (f = fMax; f < fEnd; ++f) { 2827 const PetscInt *cone, *ornt, *support; 2828 PetscInt coneNew[4], orntNew[4]; 2829 PetscInt supportNew[2], size, s, c; 2830 2831 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2832 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2833 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2834 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2835 for (r = 0; r < 2; ++r) { 2836 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 2837 2838 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 2839 orntNew[0] = ornt[0]; 2840 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 2841 orntNew[1] = ornt[1]; 2842 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 2843 orntNew[2+r] = 0; 2844 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 2845 orntNew[3-r] = 0; 2846 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2847 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2848 #if 1 2849 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 2850 for (p = 0; p < 2; ++p) { 2851 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); 2852 } 2853 for (p = 2; p < 4; ++p) { 2854 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); 2855 } 2856 #endif 2857 for (s = 0; s < size; ++s) { 2858 const PetscInt *coneCell, *orntCell, *fornt; 2859 2860 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 2861 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 2862 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 2863 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 2864 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 2865 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (fornt[c-2] < 0 ? 1-r : r))%3; 2866 } 2867 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2868 #if 1 2869 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 2870 for (p = 0; p < size; ++p) { 2871 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); 2872 } 2873 #endif 2874 } 2875 } 2876 /* Hybrid cell faces have 4 edges and 2 cells */ 2877 for (c = cMax; c < cEnd; ++c) { 2878 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 2879 const PetscInt *cone, *ornt; 2880 PetscInt coneNew[4], orntNew[4]; 2881 PetscInt supportNew[2]; 2882 2883 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2884 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2885 for (r = 0; r < 3; ++r) { 2886 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], (r+2)%3); 2887 orntNew[0] = 0; 2888 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], (r+2)%3); 2889 orntNew[1] = 0; 2890 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+GetTriSubface_Static(ornt[0], (r+2)%3)] - fMax); 2891 orntNew[2] = 0; 2892 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+GetTriSubface_Static(ornt[0], r)] - fMax); 2893 orntNew[3] = 0; 2894 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 2895 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 2896 #if 1 2897 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); 2898 for (p = 0; p < 2; ++p) { 2899 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); 2900 } 2901 for (p = 2; p < 4; ++p) { 2902 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); 2903 } 2904 #endif 2905 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 2906 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 2907 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 2908 #if 1 2909 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); 2910 for (p = 0; p < 2; ++p) { 2911 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); 2912 } 2913 #endif 2914 } 2915 } 2916 /* Interior split edges have 2 vertices and the same faces as the parent */ 2917 for (e = eStart; e < eMax; ++e) { 2918 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 2919 2920 for (r = 0; r < 2; ++r) { 2921 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 2922 const PetscInt *cone, *ornt, *support; 2923 PetscInt coneNew[2], coneSize, c, supportSize, s; 2924 2925 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 2926 coneNew[0] = vStartNew + (cone[0] - vStart); 2927 coneNew[1] = vStartNew + (cone[1] - vStart); 2928 coneNew[(r+1)%2] = newv; 2929 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2930 #if 1 2931 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2932 for (p = 0; p < 2; ++p) { 2933 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); 2934 } 2935 #endif 2936 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 2937 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2938 for (s = 0; s < supportSize; ++s) { 2939 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2940 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2941 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2942 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 2943 if (support[s] < fMax) { 2944 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 2945 } else { 2946 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 2947 } 2948 } 2949 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2950 #if 1 2951 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2952 for (p = 0; p < supportSize; ++p) { 2953 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); 2954 } 2955 #endif 2956 } 2957 } 2958 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 2959 for (f = fStart; f < fMax; ++f) { 2960 const PetscInt *cone, *ornt, *support; 2961 PetscInt coneSize, supportSize, s; 2962 2963 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2964 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2965 for (r = 0; r < 3; ++r) { 2966 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 2967 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 2968 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 2969 -1, -1, 1, 6, 0, 4, 2970 2, 5, 3, 4, -1, -1, 2971 -1, -1, 3, 6, 2, 7}; 2972 2973 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2974 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 2975 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 2976 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2977 #if 1 2978 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2979 for (p = 0; p < 2; ++p) { 2980 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); 2981 } 2982 #endif 2983 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 2984 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 2985 for (s = 0; s < supportSize; ++s) { 2986 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2987 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2988 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2989 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 2990 if (support[s] < cMax) { 2991 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 2992 er = GetTetSomethingInverse_Static(ornt[c], r); 2993 if (er == eint[c]) { 2994 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 2995 } else { 2996 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 2997 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 2998 } 2999 } else { 3000 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (GetTriSubfaceInverse_Static(ornt[c], r) + 1)%3; 3001 } 3002 } 3003 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3004 #if 1 3005 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3006 for (p = 0; p < intFaces; ++p) { 3007 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); 3008 } 3009 #endif 3010 } 3011 } 3012 /* Interior cell edges have 2 vertices and 4 faces */ 3013 for (c = cStart; c < cMax; ++c) { 3014 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3015 const PetscInt *cone, *ornt, *fcone; 3016 PetscInt coneNew[2], supportNew[4], find; 3017 3018 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3019 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3020 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 3021 find = GetTriEdge_Static(ornt[0], 0); 3022 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3023 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 3024 find = GetTriEdge_Static(ornt[2], 1); 3025 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3026 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3027 #if 1 3028 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3029 for (p = 0; p < 2; ++p) { 3030 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); 3031 } 3032 #endif 3033 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3034 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3035 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3036 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3037 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3038 #if 1 3039 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3040 for (p = 0; p < 4; ++p) { 3041 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); 3042 } 3043 #endif 3044 } 3045 /* Hybrid edges have two vertices and the same faces */ 3046 for (e = eMax; e < eEnd; ++e) { 3047 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 3048 const PetscInt *cone, *support, *fcone; 3049 PetscInt coneNew[2], size, fsize, s; 3050 3051 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3052 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3053 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3054 coneNew[0] = vStartNew + (cone[0] - vStart); 3055 coneNew[1] = vStartNew + (cone[1] - vStart); 3056 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3057 #if 1 3058 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3059 for (p = 0; p < 2; ++p) { 3060 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); 3061 } 3062 #endif 3063 for (s = 0; s < size; ++s) { 3064 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 3065 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 3066 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 3067 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 3068 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 3069 } 3070 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3071 #if 1 3072 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3073 for (p = 0; p < size; ++p) { 3074 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); 3075 } 3076 #endif 3077 } 3078 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 3079 for (f = fMax; f < fEnd; ++f) { 3080 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3081 const PetscInt *cone, *support, *ccone, *cornt; 3082 PetscInt coneNew[2], size, csize, s; 3083 3084 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3085 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3086 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3087 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 3088 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 3089 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3090 #if 1 3091 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3092 for (p = 0; p < 2; ++p) { 3093 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); 3094 } 3095 #endif 3096 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 3097 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 3098 for (s = 0; s < size; ++s) { 3099 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 3100 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 3101 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 3102 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 3103 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]); 3104 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + GetTriSubfaceInverse_Static(cornt[0], c-2); 3105 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (GetTriSubfaceInverse_Static(cornt[0], c-2) + 1)%3; 3106 } 3107 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3108 #if 1 3109 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3110 for (p = 0; p < 2+size*2; ++p) { 3111 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); 3112 } 3113 #endif 3114 } 3115 /* Interior vertices have identical supports */ 3116 for (v = vStart; v < vEnd; ++v) { 3117 const PetscInt newp = vStartNew + (v - vStart); 3118 const PetscInt *support, *cone; 3119 PetscInt size, s; 3120 3121 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3122 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3123 for (s = 0; s < size; ++s) { 3124 PetscInt r = 0; 3125 3126 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3127 if (cone[1] == v) r = 1; 3128 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3129 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 3130 } 3131 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3132 #if 1 3133 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3134 for (p = 0; p < size; ++p) { 3135 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); 3136 } 3137 #endif 3138 } 3139 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 3140 for (e = eStart; e < eMax; ++e) { 3141 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3142 const PetscInt *cone, *support; 3143 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 3144 3145 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3146 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3147 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3148 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3149 for (s = 0; s < size; ++s) { 3150 PetscInt r = 0; 3151 3152 if (support[s] < fMax) { 3153 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3154 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3155 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 3156 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 3157 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 3158 faceSize += 2; 3159 } else { 3160 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 3161 ++faceSize; 3162 } 3163 } 3164 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3165 for (s = 0; s < starSize*2; s += 2) { 3166 const PetscInt *cone, *ornt; 3167 PetscInt e01, e23; 3168 3169 if ((star[s] >= cStart) && (star[s] < cMax)) { 3170 /* Check edge 0-1 */ 3171 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3172 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3173 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 3174 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 3175 /* Check edge 2-3 */ 3176 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3177 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3178 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 3179 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 3180 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 3181 } 3182 } 3183 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3184 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3185 #if 1 3186 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3187 for (p = 0; p < 2+faceSize+cellSize; ++p) { 3188 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); 3189 } 3190 #endif 3191 } 3192 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3193 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 3194 break; 3195 case 6: 3196 /* Hex 3D */ 3197 /* 3198 Bottom (viewed from top) Top 3199 1---------2---------2 7---------2---------6 3200 | | | | | | 3201 | B 2 C | | H 2 G | 3202 | | | | | | 3203 3----3----0----1----1 3----3----0----1----1 3204 | | | | | | 3205 | A 0 D | | E 0 F | 3206 | | | | | | 3207 0---------0---------3 4---------0---------5 3208 */ 3209 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 3210 for (c = cStart; c < cEnd; ++c) { 3211 const PetscInt newp = (c - cStart)*8; 3212 const PetscInt *cone, *ornt; 3213 PetscInt coneNew[6], orntNew[6]; 3214 3215 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3216 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3217 /* A hex */ 3218 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 3219 orntNew[0] = ornt[0]; 3220 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3221 orntNew[1] = 0; 3222 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 3223 orntNew[2] = ornt[2]; 3224 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3225 orntNew[3] = 0; 3226 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3227 orntNew[4] = 0; 3228 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 3229 orntNew[5] = ornt[5]; 3230 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3231 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3232 #if 1 3233 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); 3234 for (p = 0; p < 6; ++p) { 3235 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); 3236 } 3237 #endif 3238 /* B hex */ 3239 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 3240 orntNew[0] = ornt[0]; 3241 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3242 orntNew[1] = 0; 3243 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3244 orntNew[2] = -1; 3245 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 3246 orntNew[3] = ornt[3]; 3247 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3248 orntNew[4] = 0; 3249 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 3250 orntNew[5] = ornt[5]; 3251 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3252 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3253 #if 1 3254 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); 3255 for (p = 0; p < 6; ++p) { 3256 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); 3257 } 3258 #endif 3259 /* C hex */ 3260 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 3261 orntNew[0] = ornt[0]; 3262 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3263 orntNew[1] = 0; 3264 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3265 orntNew[2] = -1; 3266 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 3267 orntNew[3] = ornt[3]; 3268 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 3269 orntNew[4] = ornt[4]; 3270 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3271 orntNew[5] = -4; 3272 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3273 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3274 #if 1 3275 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); 3276 for (p = 0; p < 6; ++p) { 3277 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); 3278 } 3279 #endif 3280 /* D hex */ 3281 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 3282 orntNew[0] = ornt[0]; 3283 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3284 orntNew[1] = 0; 3285 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 3286 orntNew[2] = ornt[2]; 3287 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3288 orntNew[3] = 0; 3289 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 3290 orntNew[4] = ornt[4]; 3291 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3292 orntNew[5] = -4; 3293 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3294 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3295 #if 1 3296 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); 3297 for (p = 0; p < 6; ++p) { 3298 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); 3299 } 3300 #endif 3301 /* E hex */ 3302 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3303 orntNew[0] = -4; 3304 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 3305 orntNew[1] = ornt[1]; 3306 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 3307 orntNew[2] = ornt[2]; 3308 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3309 orntNew[3] = 0; 3310 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3311 orntNew[4] = -1; 3312 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 3313 orntNew[5] = ornt[5]; 3314 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3315 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3316 #if 1 3317 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); 3318 for (p = 0; p < 6; ++p) { 3319 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); 3320 } 3321 #endif 3322 /* F hex */ 3323 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3324 orntNew[0] = -4; 3325 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 3326 orntNew[1] = ornt[1]; 3327 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 3328 orntNew[2] = ornt[2]; 3329 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3330 orntNew[3] = -1; 3331 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 3332 orntNew[4] = ornt[4]; 3333 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3334 orntNew[5] = 1; 3335 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3336 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3337 #if 1 3338 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); 3339 for (p = 0; p < 6; ++p) { 3340 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); 3341 } 3342 #endif 3343 /* G hex */ 3344 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3345 orntNew[0] = -4; 3346 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 3347 orntNew[1] = ornt[1]; 3348 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3349 orntNew[2] = 0; 3350 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 3351 orntNew[3] = ornt[3]; 3352 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 3353 orntNew[4] = ornt[4]; 3354 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3355 orntNew[5] = -3; 3356 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3357 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3358 #if 1 3359 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); 3360 for (p = 0; p < 6; ++p) { 3361 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); 3362 } 3363 #endif 3364 /* H hex */ 3365 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3366 orntNew[0] = -4; 3367 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 3368 orntNew[1] = ornt[1]; 3369 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3370 orntNew[2] = -1; 3371 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 3372 orntNew[3] = ornt[3]; 3373 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3374 orntNew[4] = 3; 3375 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 3376 orntNew[5] = ornt[5]; 3377 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3378 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3379 #if 1 3380 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); 3381 for (p = 0; p < 6; ++p) { 3382 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); 3383 } 3384 #endif 3385 } 3386 /* Split faces have 4 edges and the same cells as the parent */ 3387 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3388 ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 3389 for (f = fStart; f < fEnd; ++f) { 3390 for (r = 0; r < 4; ++r) { 3391 /* TODO: This can come from GetFaces_Internal() */ 3392 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}; 3393 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 3394 const PetscInt *cone, *ornt, *support; 3395 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 3396 3397 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3398 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3399 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 3400 orntNew[(r+3)%4] = ornt[(r+3)%4]; 3401 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 3402 orntNew[(r+0)%4] = ornt[r]; 3403 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 3404 orntNew[(r+1)%4] = 0; 3405 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 3406 orntNew[(r+2)%4] = -2; 3407 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3408 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3409 #if 1 3410 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3411 for (p = 0; p < 4; ++p) { 3412 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3413 } 3414 #endif 3415 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3416 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3417 for (s = 0; s < supportSize; ++s) { 3418 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3419 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3420 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3421 for (c = 0; c < coneSize; ++c) { 3422 if (cone[c] == f) break; 3423 } 3424 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 3425 } 3426 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3427 #if 1 3428 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3429 for (p = 0; p < supportSize; ++p) { 3430 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); 3431 } 3432 #endif 3433 } 3434 } 3435 /* Interior faces have 4 edges and 2 cells */ 3436 for (c = cStart; c < cEnd; ++c) { 3437 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}; 3438 const PetscInt *cone, *ornt; 3439 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 3440 3441 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3442 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3443 /* A-D face */ 3444 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 3445 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 3446 orntNew[0] = 0; 3447 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3448 orntNew[1] = 0; 3449 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3450 orntNew[2] = -2; 3451 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 3452 orntNew[3] = -2; 3453 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3454 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3455 #if 1 3456 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3457 for (p = 0; p < 4; ++p) { 3458 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); 3459 } 3460 #endif 3461 /* C-D face */ 3462 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 3463 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 3464 orntNew[0] = 0; 3465 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3466 orntNew[1] = 0; 3467 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3468 orntNew[2] = -2; 3469 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 3470 orntNew[3] = -2; 3471 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3472 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3473 #if 1 3474 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3475 for (p = 0; p < 4; ++p) { 3476 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); 3477 } 3478 #endif 3479 /* B-C face */ 3480 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 3481 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 3482 orntNew[0] = -2; 3483 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 3484 orntNew[1] = 0; 3485 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3486 orntNew[2] = 0; 3487 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3488 orntNew[3] = -2; 3489 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3490 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3491 #if 1 3492 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3493 for (p = 0; p < 4; ++p) { 3494 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); 3495 } 3496 #endif 3497 /* A-B face */ 3498 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 3499 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 3500 orntNew[0] = -2; 3501 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 3502 orntNew[1] = 0; 3503 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3504 orntNew[2] = 0; 3505 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3506 orntNew[3] = -2; 3507 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3508 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3509 #if 1 3510 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3511 for (p = 0; p < 4; ++p) { 3512 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); 3513 } 3514 #endif 3515 /* E-F face */ 3516 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 3517 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3518 orntNew[0] = -2; 3519 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 3520 orntNew[1] = -2; 3521 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 3522 orntNew[2] = 0; 3523 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3524 orntNew[3] = 0; 3525 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3526 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3527 #if 1 3528 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3529 for (p = 0; p < 4; ++p) { 3530 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); 3531 } 3532 #endif 3533 /* F-G face */ 3534 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 3535 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3536 orntNew[0] = -2; 3537 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 3538 orntNew[1] = -2; 3539 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 3540 orntNew[2] = 0; 3541 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3542 orntNew[3] = 0; 3543 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3544 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3545 #if 1 3546 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3547 for (p = 0; p < 4; ++p) { 3548 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); 3549 } 3550 #endif 3551 /* G-H face */ 3552 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 3553 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 3554 orntNew[0] = -2; 3555 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 3556 orntNew[1] = 0; 3557 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3558 orntNew[2] = 0; 3559 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3560 orntNew[3] = -2; 3561 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3562 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3563 #if 1 3564 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3565 for (p = 0; p < 4; ++p) { 3566 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); 3567 } 3568 #endif 3569 /* E-H face */ 3570 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 3571 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3572 orntNew[0] = -2; 3573 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 3574 orntNew[1] = -2; 3575 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 3576 orntNew[2] = 0; 3577 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3578 orntNew[3] = 0; 3579 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3580 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3581 #if 1 3582 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3583 for (p = 0; p < 4; ++p) { 3584 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); 3585 } 3586 #endif 3587 /* A-E face */ 3588 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 3589 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 3590 orntNew[0] = 0; 3591 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3592 orntNew[1] = 0; 3593 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3594 orntNew[2] = -2; 3595 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 3596 orntNew[3] = -2; 3597 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3598 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3599 #if 1 3600 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3601 for (p = 0; p < 4; ++p) { 3602 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); 3603 } 3604 #endif 3605 /* D-F face */ 3606 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 3607 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 3608 orntNew[0] = -2; 3609 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 3610 orntNew[1] = 0; 3611 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3612 orntNew[2] = 0; 3613 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3614 orntNew[3] = -2; 3615 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3616 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3617 #if 1 3618 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3619 for (p = 0; p < 4; ++p) { 3620 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); 3621 } 3622 #endif 3623 /* C-G face */ 3624 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 3625 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3626 orntNew[0] = -2; 3627 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 3628 orntNew[1] = -2; 3629 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 3630 orntNew[2] = 0; 3631 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3632 orntNew[3] = 0; 3633 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3634 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3635 #if 1 3636 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3637 for (p = 0; p < 4; ++p) { 3638 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); 3639 } 3640 #endif 3641 /* B-H face */ 3642 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 3643 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3644 orntNew[0] = 0; 3645 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3646 orntNew[1] = -2; 3647 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 3648 orntNew[2] = -2; 3649 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 3650 orntNew[3] = 0; 3651 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3652 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3653 #if 1 3654 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3655 for (p = 0; p < 4; ++p) { 3656 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); 3657 } 3658 #endif 3659 for (r = 0; r < 12; ++r) { 3660 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 3661 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 3662 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 3663 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3664 #if 1 3665 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3666 for (p = 0; p < 2; ++p) { 3667 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); 3668 } 3669 #endif 3670 } 3671 } 3672 /* Split edges have 2 vertices and the same faces as the parent */ 3673 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3674 for (e = eStart; e < eEnd; ++e) { 3675 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3676 3677 for (r = 0; r < 2; ++r) { 3678 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3679 const PetscInt *cone, *ornt, *support; 3680 PetscInt coneNew[2], coneSize, c, supportSize, s; 3681 3682 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3683 coneNew[0] = vStartNew + (cone[0] - vStart); 3684 coneNew[1] = vStartNew + (cone[1] - vStart); 3685 coneNew[(r+1)%2] = newv; 3686 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3687 #if 1 3688 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3689 for (p = 0; p < 2; ++p) { 3690 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); 3691 } 3692 #endif 3693 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3694 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3695 for (s = 0; s < supportSize; ++s) { 3696 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3697 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3698 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3699 for (c = 0; c < coneSize; ++c) { 3700 if (cone[c] == e) break; 3701 } 3702 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 3703 } 3704 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3705 #if 1 3706 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3707 for (p = 0; p < supportSize; ++p) { 3708 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); 3709 } 3710 #endif 3711 } 3712 } 3713 /* Face edges have 2 vertices and 2+cells faces */ 3714 for (f = fStart; f < fEnd; ++f) { 3715 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}; 3716 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 3717 const PetscInt *cone, *coneCell, *orntCell, *support; 3718 PetscInt coneNew[2], coneSize, c, supportSize, s; 3719 3720 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3721 for (r = 0; r < 4; ++r) { 3722 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 3723 3724 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 3725 coneNew[1] = newv; 3726 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3727 #if 1 3728 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3729 for (p = 0; p < 2; ++p) { 3730 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); 3731 } 3732 #endif 3733 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3734 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3735 supportRef[0] = fStartNew + (f - fStart)*4 + r; 3736 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 3737 for (s = 0; s < supportSize; ++s) { 3738 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3739 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 3740 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 3741 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 3742 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 3743 } 3744 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3745 #if 1 3746 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3747 for (p = 0; p < 2+supportSize; ++p) { 3748 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); 3749 } 3750 #endif 3751 } 3752 } 3753 /* Cell edges have 2 vertices and 4 faces */ 3754 for (c = cStart; c < cEnd; ++c) { 3755 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}; 3756 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 3757 const PetscInt *cone; 3758 PetscInt coneNew[2], supportNew[4]; 3759 3760 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3761 for (r = 0; r < 6; ++r) { 3762 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 3763 3764 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 3765 coneNew[1] = newv; 3766 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3767 #if 1 3768 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3769 for (p = 0; p < 2; ++p) { 3770 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); 3771 } 3772 #endif 3773 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 3774 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3775 #if 1 3776 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3777 for (p = 0; p < 4; ++p) { 3778 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); 3779 } 3780 #endif 3781 } 3782 } 3783 /* Old vertices have identical supports */ 3784 for (v = vStart; v < vEnd; ++v) { 3785 const PetscInt newp = vStartNew + (v - vStart); 3786 const PetscInt *support, *cone; 3787 PetscInt size, s; 3788 3789 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3790 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3791 for (s = 0; s < size; ++s) { 3792 PetscInt r = 0; 3793 3794 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3795 if (cone[1] == v) r = 1; 3796 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3797 } 3798 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3799 #if 1 3800 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3801 for (p = 0; p < size; ++p) { 3802 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); 3803 } 3804 #endif 3805 } 3806 /* Edge vertices have 2 + faces supports */ 3807 for (e = eStart; e < eEnd; ++e) { 3808 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3809 const PetscInt *cone, *support; 3810 PetscInt size, s; 3811 3812 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3813 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3814 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3815 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3816 for (s = 0; s < size; ++s) { 3817 PetscInt r; 3818 3819 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3820 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 3821 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 3822 } 3823 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3824 #if 1 3825 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3826 for (p = 0; p < 2+size; ++p) { 3827 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); 3828 } 3829 #endif 3830 } 3831 /* Face vertices have 4 + cells supports */ 3832 for (f = fStart; f < fEnd; ++f) { 3833 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 3834 const PetscInt *cone, *support; 3835 PetscInt size, s; 3836 3837 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3838 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3839 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 3840 for (s = 0; s < size; ++s) { 3841 PetscInt r; 3842 3843 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3844 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 3845 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 3846 } 3847 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3848 #if 1 3849 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3850 for (p = 0; p < 4+size; ++p) { 3851 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); 3852 } 3853 #endif 3854 } 3855 /* Cell vertices have 6 supports */ 3856 for (c = cStart; c < cEnd; ++c) { 3857 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 3858 PetscInt supportNew[6]; 3859 3860 for (r = 0; r < 6; ++r) { 3861 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 3862 } 3863 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3864 } 3865 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3866 break; 3867 case 8: 3868 /* Hybrid Hex 3D */ 3869 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 3870 /* 3871 Bottom (viewed from top) Top 3872 1---------2---------2 7---------2---------6 3873 | | | | | | 3874 | B 2 C | | H 2 G | 3875 | | | | | | 3876 3----3----0----1----1 3----3----0----1----1 3877 | | | | | | 3878 | A 0 D | | E 0 F | 3879 | | | | | | 3880 0---------0---------3 4---------0---------5 3881 */ 3882 /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 3883 for (c = cStart; c < cMax; ++c) { 3884 const PetscInt newp = (c - cStart)*8; 3885 const PetscInt *cone, *ornt; 3886 PetscInt coneNew[6], orntNew[6]; 3887 3888 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3889 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3890 /* A hex */ 3891 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 3892 orntNew[0] = ornt[0]; 3893 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3894 orntNew[1] = 0; 3895 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 3896 orntNew[2] = ornt[2]; 3897 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3898 orntNew[3] = 0; 3899 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3900 orntNew[4] = 0; 3901 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 3902 orntNew[5] = ornt[5]; 3903 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3904 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3905 #if 1 3906 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); 3907 for (p = 0; p < 6; ++p) { 3908 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); 3909 } 3910 #endif 3911 /* B hex */ 3912 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 3913 orntNew[0] = ornt[0]; 3914 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3915 orntNew[1] = 0; 3916 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3917 orntNew[2] = -1; 3918 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 3919 orntNew[3] = ornt[3]; 3920 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3921 orntNew[4] = 0; 3922 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 3923 orntNew[5] = ornt[5]; 3924 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3925 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3926 #if 1 3927 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); 3928 for (p = 0; p < 6; ++p) { 3929 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); 3930 } 3931 #endif 3932 /* C hex */ 3933 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 3934 orntNew[0] = ornt[0]; 3935 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3936 orntNew[1] = 0; 3937 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3938 orntNew[2] = -1; 3939 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 3940 orntNew[3] = ornt[3]; 3941 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 3942 orntNew[4] = ornt[4]; 3943 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3944 orntNew[5] = -4; 3945 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3946 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3947 #if 1 3948 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); 3949 for (p = 0; p < 6; ++p) { 3950 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); 3951 } 3952 #endif 3953 /* D hex */ 3954 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 3955 orntNew[0] = ornt[0]; 3956 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3957 orntNew[1] = 0; 3958 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 3959 orntNew[2] = ornt[2]; 3960 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3961 orntNew[3] = 0; 3962 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 3963 orntNew[4] = ornt[4]; 3964 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3965 orntNew[5] = -4; 3966 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3967 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3968 #if 1 3969 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); 3970 for (p = 0; p < 6; ++p) { 3971 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); 3972 } 3973 #endif 3974 /* E hex */ 3975 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3976 orntNew[0] = -4; 3977 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 3978 orntNew[1] = ornt[1]; 3979 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 3980 orntNew[2] = ornt[2]; 3981 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3982 orntNew[3] = 0; 3983 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3984 orntNew[4] = -1; 3985 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 3986 orntNew[5] = ornt[5]; 3987 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3988 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3989 #if 1 3990 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); 3991 for (p = 0; p < 6; ++p) { 3992 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); 3993 } 3994 #endif 3995 /* F hex */ 3996 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3997 orntNew[0] = -4; 3998 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 3999 orntNew[1] = ornt[1]; 4000 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 4001 orntNew[2] = ornt[2]; 4002 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4003 orntNew[3] = -1; 4004 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 4005 orntNew[4] = ornt[4]; 4006 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4007 orntNew[5] = 1; 4008 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 4009 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 4010 #if 1 4011 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); 4012 for (p = 0; p < 6; ++p) { 4013 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); 4014 } 4015 #endif 4016 /* G hex */ 4017 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4018 orntNew[0] = -4; 4019 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 4020 orntNew[1] = ornt[1]; 4021 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4022 orntNew[2] = 0; 4023 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 4024 orntNew[3] = ornt[3]; 4025 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 4026 orntNew[4] = ornt[4]; 4027 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4028 orntNew[5] = -3; 4029 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 4030 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 4031 #if 1 4032 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); 4033 for (p = 0; p < 6; ++p) { 4034 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); 4035 } 4036 #endif 4037 /* H hex */ 4038 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4039 orntNew[0] = -4; 4040 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 4041 orntNew[1] = ornt[1]; 4042 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4043 orntNew[2] = -1; 4044 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 4045 orntNew[3] = ornt[3]; 4046 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4047 orntNew[4] = 3; 4048 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 4049 orntNew[5] = ornt[5]; 4050 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 4051 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 4052 #if 1 4053 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); 4054 for (p = 0; p < 6; ++p) { 4055 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); 4056 } 4057 #endif 4058 } 4059 /* Hybrid cells have 6 faces: Front, Back, Sides */ 4060 /* 4061 3---------2---------2 4062 | | | 4063 | D 2 C | 4064 | | | 4065 3----3----0----1----1 4066 | | | 4067 | A 0 B | 4068 | | | 4069 0---------0---------1 4070 */ 4071 for (c = cMax; c < cEnd; ++c) { 4072 const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4; 4073 const PetscInt *cone, *ornt, *fornt; 4074 PetscInt coneNew[6], orntNew[6]; 4075 4076 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4077 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4078 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 4079 for (r = 0; r < 4; ++r) { 4080 PetscInt subfA = GetQuadSubface_Static(ornt[0], r); 4081 PetscInt edgeA = GetQuadEdge_Static(ornt[0], r); 4082 PetscInt edgeB = (edgeA+3)%4; 4083 if (ornt[0] != ornt[1]) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent ordering for matching ends of hybrid cell %d: %d != %d", c, ornt[0], ornt[1]); 4084 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA; 4085 orntNew[0] = ornt[0]; 4086 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA; 4087 orntNew[1] = ornt[0]; 4088 coneNew[(r+0)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[edgeA+2] - fMax)*2 + (fornt[edgeA] < 0 ? 1 : 0); 4089 orntNew[(r+0)%4+2] = ornt[edgeA]; 4090 coneNew[(r+1)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA; 4091 orntNew[(r+1)%4+2] = 0; 4092 coneNew[(r+2)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB; 4093 orntNew[(r+2)%4+2] = -2; 4094 coneNew[(r+3)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[edgeB+2] - fMax)*2 + (fornt[edgeB] < 0 ? 0 : 1); 4095 orntNew[(r+3)%4+2] = ornt[edgeB]; 4096 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4097 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4098 #if 1 4099 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); 4100 for (p = 0; p < 2; ++p) { 4101 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); 4102 } 4103 for (p = 2; p < 6; ++p) { 4104 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); 4105 } 4106 #endif 4107 } 4108 } 4109 /* Interior split faces have 4 edges and the same cells as the parent */ 4110 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4111 ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 4112 for (f = fStart; f < fMax; ++f) { 4113 for (r = 0; r < 4; ++r) { 4114 /* TODO: This can come from GetFaces_Internal() */ 4115 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}; 4116 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 4117 const PetscInt *cone, *ornt, *support; 4118 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 4119 4120 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4121 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4122 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 4123 orntNew[(r+3)%4] = ornt[(r+3)%4]; 4124 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 4125 orntNew[(r+0)%4] = ornt[r]; 4126 coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 4127 orntNew[(r+1)%4] = 0; 4128 coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4; 4129 orntNew[(r+2)%4] = -2; 4130 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4131 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4132 #if 1 4133 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4134 for (p = 0; p < 4; ++p) { 4135 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); 4136 } 4137 #endif 4138 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4139 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4140 for (s = 0; s < supportSize; ++s) { 4141 PetscInt subf; 4142 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4143 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4144 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4145 for (c = 0; c < coneSize; ++c) { 4146 if (cone[c] == f) break; 4147 } 4148 subf = GetQuadSubfaceInverse_Static(ornt[c], r); 4149 if (support[s] < cMax) { 4150 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf]; 4151 } else { 4152 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf; 4153 } 4154 } 4155 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4156 #if 1 4157 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4158 for (p = 0; p < supportSize; ++p) { 4159 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); 4160 } 4161 #endif 4162 } 4163 } 4164 /* Interior faces have 4 edges and 2 cells */ 4165 for (c = cStart; c < cMax; ++c) { 4166 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}; 4167 const PetscInt *cone, *ornt; 4168 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 4169 4170 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4171 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4172 /* A-D face */ 4173 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; 4174 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 4175 orntNew[0] = 0; 4176 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4177 orntNew[1] = 0; 4178 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4179 orntNew[2] = -2; 4180 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 4181 orntNew[3] = -2; 4182 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4183 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4184 #if 1 4185 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4186 for (p = 0; p < 4; ++p) { 4187 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); 4188 } 4189 #endif 4190 /* C-D face */ 4191 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; 4192 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 4193 orntNew[0] = 0; 4194 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4195 orntNew[1] = 0; 4196 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4197 orntNew[2] = -2; 4198 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 4199 orntNew[3] = -2; 4200 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4201 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4202 #if 1 4203 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4204 for (p = 0; p < 4; ++p) { 4205 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); 4206 } 4207 #endif 4208 /* B-C face */ 4209 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; 4210 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 4211 orntNew[0] = -2; 4212 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 4213 orntNew[1] = 0; 4214 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4215 orntNew[2] = 0; 4216 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4217 orntNew[3] = -2; 4218 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4219 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4220 #if 1 4221 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4222 for (p = 0; p < 4; ++p) { 4223 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); 4224 } 4225 #endif 4226 /* A-B face */ 4227 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; 4228 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 4229 orntNew[0] = -2; 4230 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 4231 orntNew[1] = 0; 4232 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4233 orntNew[2] = 0; 4234 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4235 orntNew[3] = -2; 4236 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4237 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4238 #if 1 4239 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4240 for (p = 0; p < 4; ++p) { 4241 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); 4242 } 4243 #endif 4244 /* E-F face */ 4245 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; 4246 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4247 orntNew[0] = -2; 4248 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 4249 orntNew[1] = -2; 4250 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 4251 orntNew[2] = 0; 4252 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4253 orntNew[3] = 0; 4254 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4255 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4256 #if 1 4257 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4258 for (p = 0; p < 4; ++p) { 4259 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); 4260 } 4261 #endif 4262 /* F-G face */ 4263 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; 4264 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4265 orntNew[0] = -2; 4266 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 4267 orntNew[1] = -2; 4268 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 4269 orntNew[2] = 0; 4270 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4271 orntNew[3] = 0; 4272 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4273 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4274 #if 1 4275 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4276 for (p = 0; p < 4; ++p) { 4277 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); 4278 } 4279 #endif 4280 /* G-H face */ 4281 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; 4282 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 4283 orntNew[0] = -2; 4284 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 4285 orntNew[1] = 0; 4286 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4287 orntNew[2] = 0; 4288 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4289 orntNew[3] = -2; 4290 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4291 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4292 #if 1 4293 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4294 for (p = 0; p < 4; ++p) { 4295 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); 4296 } 4297 #endif 4298 /* E-H face */ 4299 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; 4300 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4301 orntNew[0] = -2; 4302 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 4303 orntNew[1] = -2; 4304 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 4305 orntNew[2] = 0; 4306 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4307 orntNew[3] = 0; 4308 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4309 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4310 #if 1 4311 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4312 for (p = 0; p < 4; ++p) { 4313 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); 4314 } 4315 #endif 4316 /* A-E face */ 4317 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; 4318 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 4319 orntNew[0] = 0; 4320 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4321 orntNew[1] = 0; 4322 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4323 orntNew[2] = -2; 4324 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 4325 orntNew[3] = -2; 4326 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4327 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4328 #if 1 4329 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4330 for (p = 0; p < 4; ++p) { 4331 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); 4332 } 4333 #endif 4334 /* D-F face */ 4335 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; 4336 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 4337 orntNew[0] = -2; 4338 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 4339 orntNew[1] = 0; 4340 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4341 orntNew[2] = 0; 4342 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4343 orntNew[3] = -2; 4344 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4345 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4346 #if 1 4347 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4348 for (p = 0; p < 4; ++p) { 4349 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); 4350 } 4351 #endif 4352 /* C-G face */ 4353 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; 4354 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4355 orntNew[0] = -2; 4356 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 4357 orntNew[1] = -2; 4358 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 4359 orntNew[2] = 0; 4360 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4361 orntNew[3] = 0; 4362 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4363 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4364 #if 1 4365 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4366 for (p = 0; p < 4; ++p) { 4367 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); 4368 } 4369 #endif 4370 /* B-H face */ 4371 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; 4372 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4373 orntNew[0] = 0; 4374 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4375 orntNew[1] = -2; 4376 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 4377 orntNew[2] = -2; 4378 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 4379 orntNew[3] = 0; 4380 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4381 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4382 #if 1 4383 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4384 for (p = 0; p < 4; ++p) { 4385 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); 4386 } 4387 #endif 4388 for (r = 0; r < 12; ++r) { 4389 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 4390 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 4391 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 4392 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4393 #if 1 4394 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4395 for (p = 0; p < 2; ++p) { 4396 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); 4397 } 4398 #endif 4399 } 4400 } 4401 /* Hybrid split faces have 4 edges and same cells */ 4402 for (f = fMax; f < fEnd; ++f) { 4403 const PetscInt *cone, *ornt, *support; 4404 PetscInt coneNew[4], orntNew[4]; 4405 PetscInt supportNew[2], size, s, c; 4406 4407 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4408 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4409 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4410 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4411 for (r = 0; r < 2; ++r) { 4412 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 4413 4414 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 4415 orntNew[0] = ornt[0]; 4416 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 4417 orntNew[1] = ornt[1]; 4418 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax); 4419 orntNew[2+r] = 0; 4420 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 4421 orntNew[3-r] = 0; 4422 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4423 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4424 #if 1 4425 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 4426 for (p = 0; p < 2; ++p) { 4427 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); 4428 } 4429 for (p = 2; p < 4; ++p) { 4430 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); 4431 } 4432 #endif 4433 for (s = 0; s < size; ++s) { 4434 const PetscInt *coneCell, *orntCell, *fornt; 4435 4436 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4437 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4438 for (c = 2; c < 6; ++c) if (coneCell[c] == f) break; 4439 if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 4440 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 4441 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (fornt[c-2] < 0 ? 1-r : r))%4; 4442 } 4443 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4444 #if 1 4445 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 4446 for (p = 0; p < size; ++p) { 4447 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); 4448 } 4449 #endif 4450 } 4451 } 4452 /* Hybrid cell faces have 4 edges and 2 cells */ 4453 for (c = cMax; c < cEnd; ++c) { 4454 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4; 4455 const PetscInt *cone, *ornt; 4456 PetscInt coneNew[4], orntNew[4]; 4457 PetscInt supportNew[2]; 4458 4459 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4460 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4461 for (r = 0; r < 4; ++r) { 4462 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r); 4463 orntNew[0] = 0; 4464 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r); 4465 orntNew[1] = 0; 4466 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax); 4467 orntNew[2] = 0; 4468 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 4469 orntNew[3] = 0; 4470 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4471 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4472 #if 1 4473 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); 4474 for (p = 0; p < 2; ++p) { 4475 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); 4476 } 4477 for (p = 2; p < 4; ++p) { 4478 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); 4479 } 4480 #endif 4481 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r); 4482 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4); 4483 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 4484 #if 1 4485 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); 4486 for (p = 0; p < 2; ++p) { 4487 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); 4488 } 4489 #endif 4490 } 4491 } 4492 /* Interior split edges have 2 vertices and the same faces as the parent */ 4493 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4494 for (e = eStart; e < eMax; ++e) { 4495 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4496 4497 for (r = 0; r < 2; ++r) { 4498 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4499 const PetscInt *cone, *ornt, *support; 4500 PetscInt coneNew[2], coneSize, c, supportSize, s; 4501 4502 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4503 coneNew[0] = vStartNew + (cone[0] - vStart); 4504 coneNew[1] = vStartNew + (cone[1] - vStart); 4505 coneNew[(r+1)%2] = newv; 4506 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4507 #if 1 4508 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4509 for (p = 0; p < 2; ++p) { 4510 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); 4511 } 4512 #endif 4513 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4514 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4515 for (s = 0; s < supportSize; ++s) { 4516 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4517 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4518 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4519 for (c = 0; c < coneSize; ++c) { 4520 if (cone[c] == e) break; 4521 } 4522 if (support[s] < fMax) { 4523 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4; 4524 } else { 4525 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 4526 } 4527 } 4528 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4529 #if 1 4530 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4531 for (p = 0; p < supportSize; ++p) { 4532 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); 4533 } 4534 #endif 4535 } 4536 } 4537 /* Interior face edges have 2 vertices and 2+cells faces */ 4538 for (f = fStart; f < fMax; ++f) { 4539 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}; 4540 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 4541 const PetscInt *cone, *coneCell, *orntCell, *support; 4542 PetscInt coneNew[2], coneSize, c, supportSize, s; 4543 4544 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4545 for (r = 0; r < 4; ++r) { 4546 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 4547 4548 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 4549 coneNew[1] = newv; 4550 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4551 #if 1 4552 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4553 for (p = 0; p < 2; ++p) { 4554 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); 4555 } 4556 #endif 4557 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4558 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4559 supportRef[0] = fStartNew + (f - fStart)*4 + r; 4560 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 4561 for (s = 0; s < supportSize; ++s) { 4562 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4563 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4564 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4565 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 4566 if (support[s] < cMax) { 4567 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 4568 } else { 4569 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + GetQuadEdgeInverse_Static(orntCell[c], r); 4570 } 4571 } 4572 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4573 #if 1 4574 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4575 for (p = 0; p < 2+supportSize; ++p) { 4576 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); 4577 } 4578 #endif 4579 } 4580 } 4581 /* Interior cell edges have 2 vertices and 4 faces */ 4582 for (c = cStart; c < cMax; ++c) { 4583 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}; 4584 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 4585 const PetscInt *cone; 4586 PetscInt coneNew[2], supportNew[4]; 4587 4588 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4589 for (r = 0; r < 6; ++r) { 4590 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 4591 4592 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 4593 coneNew[1] = newv; 4594 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4595 #if 1 4596 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4597 for (p = 0; p < 2; ++p) { 4598 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); 4599 } 4600 #endif 4601 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 4602 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4603 #if 1 4604 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4605 for (p = 0; p < 4; ++p) { 4606 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); 4607 } 4608 #endif 4609 } 4610 } 4611 /* Hybrid edges have two vertices and the same faces */ 4612 for (e = eMax; e < eEnd; ++e) { 4613 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 4614 const PetscInt *cone, *support, *fcone; 4615 PetscInt coneNew[2], size, fsize, s; 4616 4617 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4618 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4619 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4620 coneNew[0] = vStartNew + (cone[0] - vStart); 4621 coneNew[1] = vStartNew + (cone[1] - vStart); 4622 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4623 #if 1 4624 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4625 for (p = 0; p < 2; ++p) { 4626 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); 4627 } 4628 #endif 4629 for (s = 0; s < size; ++s) { 4630 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 4631 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 4632 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 4633 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 4634 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2; 4635 } 4636 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4637 #if 1 4638 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4639 for (p = 0; p < size; ++p) { 4640 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); 4641 } 4642 #endif 4643 } 4644 /* Hybrid face edges have 2 vertices and 2+cells faces */ 4645 for (f = fMax; f < fEnd; ++f) { 4646 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 4647 const PetscInt *cone, *support, *ccone, *cornt; 4648 PetscInt coneNew[2], size, csize, s; 4649 4650 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4651 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4652 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4653 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 4654 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 4655 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4656 #if 1 4657 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4658 for (p = 0; p < 2; ++p) { 4659 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); 4660 } 4661 #endif 4662 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0; 4663 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1; 4664 for (s = 0; s < size; ++s) { 4665 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 4666 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 4667 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 4668 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 4669 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]); 4670 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + GetQuadSubfaceInverse_Static(cornt[0], c-2); 4671 } 4672 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4673 #if 1 4674 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4675 for (p = 0; p < 2+size; ++p) { 4676 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); 4677 } 4678 #endif 4679 } 4680 /* Hybrid cell edges have 2 vertices and 4 faces */ 4681 for (c = cMax; c < cEnd; ++c) { 4682 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 4683 const PetscInt *cone, *support; 4684 PetscInt coneNew[2], size; 4685 4686 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4687 ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr); 4688 ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr); 4689 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 4690 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 4691 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4692 #if 1 4693 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4694 for (p = 0; p < 2; ++p) { 4695 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); 4696 } 4697 #endif 4698 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0; 4699 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1; 4700 supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2; 4701 supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3; 4702 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4703 #if 1 4704 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4705 for (p = 0; p < 4; ++p) { 4706 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); 4707 } 4708 #endif 4709 } 4710 /* Interior vertices have identical supports */ 4711 for (v = vStart; v < vEnd; ++v) { 4712 const PetscInt newp = vStartNew + (v - vStart); 4713 const PetscInt *support, *cone; 4714 PetscInt size, s; 4715 4716 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4717 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4718 for (s = 0; s < size; ++s) { 4719 PetscInt r = 0; 4720 4721 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4722 if (cone[1] == v) r = 1; 4723 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4724 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax); 4725 } 4726 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4727 #if 1 4728 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4729 for (p = 0; p < size; ++p) { 4730 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); 4731 } 4732 #endif 4733 } 4734 /* Interior edge vertices have 2 + faces supports */ 4735 for (e = eStart; e < eMax; ++e) { 4736 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4737 const PetscInt *cone, *support; 4738 PetscInt size, s; 4739 4740 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4741 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4742 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4743 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4744 for (s = 0; s < size; ++s) { 4745 PetscInt r; 4746 4747 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4748 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 4749 if (support[s] < fMax) { 4750 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r; 4751 } else { 4752 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax); 4753 } 4754 } 4755 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4756 #if 1 4757 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4758 for (p = 0; p < 2+size; ++p) { 4759 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); 4760 } 4761 #endif 4762 } 4763 /* Interior face vertices have 4 + cells supports */ 4764 for (f = fStart; f < fMax; ++f) { 4765 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 4766 const PetscInt *cone, *support; 4767 PetscInt size, s; 4768 4769 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4770 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4771 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 4772 for (s = 0; s < size; ++s) { 4773 PetscInt r; 4774 4775 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4776 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 4777 if (support[s] < cMax) { 4778 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r; 4779 } else { 4780 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax); 4781 } 4782 } 4783 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4784 #if 1 4785 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4786 for (p = 0; p < 4+size; ++p) { 4787 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); 4788 } 4789 #endif 4790 } 4791 /* Cell vertices have 6 supports */ 4792 for (c = cStart; c < cMax; ++c) { 4793 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 4794 PetscInt supportNew[6]; 4795 4796 for (r = 0; r < 6; ++r) { 4797 supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 4798 } 4799 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4800 } 4801 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4802 break; 4803 default: 4804 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 4805 } 4806 PetscFunctionReturn(0); 4807 } 4808 4809 #undef __FUNCT__ 4810 #define __FUNCT__ "CellRefinerSetCoordinates" 4811 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 4812 { 4813 PetscSection coordSection, coordSectionNew; 4814 Vec coordinates, coordinatesNew; 4815 PetscScalar *coords, *coordsNew; 4816 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 4817 PetscInt dim, depth, coordSizeNew, cStart, cEnd, cMax, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 4818 PetscErrorCode ierr; 4819 4820 PetscFunctionBegin; 4821 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 4822 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 4823 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 4824 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 4825 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 4826 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 4827 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 4828 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);} 4829 ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr); 4830 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 4831 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 4832 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 4833 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dim);CHKERRQ(ierr); 4834 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 4835 if (cMax < 0) cMax = cEnd; 4836 if (fMax < 0) fMax = fEnd; 4837 if (eMax < 0) eMax = eEnd; 4838 /* All vertices have the dim coordinates */ 4839 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 4840 ierr = PetscSectionSetDof(coordSectionNew, v, dim);CHKERRQ(ierr); 4841 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dim);CHKERRQ(ierr); 4842 } 4843 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 4844 ierr = DMSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr); 4845 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 4846 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 4847 ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr); 4848 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 4849 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 4850 ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr); 4851 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 4852 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 4853 switch (refiner) { 4854 case 0: break; 4855 case 6: /* Hex 3D */ 4856 case 8: /* Hybrid Hex 3D */ 4857 /* Face vertices have the average of corner coordinates */ 4858 for (f = fStart; f < fMax; ++f) { 4859 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 4860 PetscInt *cone = NULL; 4861 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 4862 4863 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 4864 for (p = 0; p < closureSize*2; p += 2) { 4865 const PetscInt point = cone[p]; 4866 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 4867 } 4868 for (v = 0; v < coneSize; ++v) { 4869 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 4870 } 4871 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 4872 for (d = 0; d < dim; ++d) { 4873 coordsNew[offnew+d] = 0.0; 4874 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 4875 coordsNew[offnew+d] /= coneSize; 4876 } 4877 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 4878 } 4879 case 2: /* Hex 2D */ 4880 /* Cell vertices have the average of corner coordinates */ 4881 for (c = cStart; c < cMax; ++c) { 4882 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0); 4883 PetscInt *cone = NULL; 4884 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 4885 4886 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 4887 for (p = 0; p < closureSize*2; p += 2) { 4888 const PetscInt point = cone[p]; 4889 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 4890 } 4891 for (v = 0; v < coneSize; ++v) { 4892 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 4893 } 4894 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 4895 for (d = 0; d < dim; ++d) { 4896 coordsNew[offnew+d] = 0.0; 4897 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 4898 coordsNew[offnew+d] /= coneSize; 4899 } 4900 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 4901 } 4902 case 1: /* Simplicial 2D */ 4903 case 3: /* Hybrid Simplicial 2D */ 4904 case 5: /* Simplicial 3D */ 4905 case 7: /* Hybrid Simplicial 3D */ 4906 /* Edge vertices have the average of endpoint coordinates */ 4907 for (e = eStart; e < eMax; ++e) { 4908 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4909 const PetscInt *cone; 4910 PetscInt coneSize, offA, offB, offnew, d; 4911 4912 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 4913 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 4914 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4915 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 4916 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 4917 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 4918 for (d = 0; d < dim; ++d) { 4919 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]); 4920 } 4921 } 4922 /* Old vertices have the same coordinates */ 4923 for (v = vStart; v < vEnd; ++v) { 4924 const PetscInt newv = vStartNew + (v - vStart); 4925 PetscInt off, offnew, d; 4926 4927 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 4928 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 4929 for (d = 0; d < dim; ++d) { 4930 coordsNew[offnew+d] = coords[off+d]; 4931 } 4932 } 4933 break; 4934 default: 4935 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 4936 } 4937 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 4938 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 4939 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 4940 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 4941 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 4942 PetscFunctionReturn(0); 4943 } 4944 4945 #undef __FUNCT__ 4946 #define __FUNCT__ "DMPlexCreateProcessSF" 4947 static PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 4948 { 4949 PetscInt numRoots, numLeaves, l; 4950 const PetscInt *localPoints; 4951 const PetscSFNode *remotePoints; 4952 PetscInt *localPointsNew; 4953 PetscSFNode *remotePointsNew; 4954 PetscInt *ranks, *ranksNew; 4955 PetscErrorCode ierr; 4956 4957 PetscFunctionBegin; 4958 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 4959 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 4960 for (l = 0; l < numLeaves; ++l) { 4961 ranks[l] = remotePoints[l].rank; 4962 } 4963 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 4964 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 4965 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 4966 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 4967 for (l = 0; l < numLeaves; ++l) { 4968 ranksNew[l] = ranks[l]; 4969 localPointsNew[l] = l; 4970 remotePointsNew[l].index = 0; 4971 remotePointsNew[l].rank = ranksNew[l]; 4972 } 4973 ierr = PetscFree(ranks);CHKERRQ(ierr); 4974 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr); 4975 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 4976 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 4977 ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 4978 PetscFunctionReturn(0); 4979 } 4980 4981 #undef __FUNCT__ 4982 #define __FUNCT__ "CellRefinerCreateSF" 4983 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 4984 { 4985 PetscSF sf, sfNew, sfProcess; 4986 IS processRanks; 4987 MPI_Datatype depthType; 4988 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 4989 const PetscInt *localPoints, *neighbors; 4990 const PetscSFNode *remotePoints; 4991 PetscInt *localPointsNew; 4992 PetscSFNode *remotePointsNew; 4993 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 4994 PetscInt depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 4995 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 4996 PetscErrorCode ierr; 4997 4998 PetscFunctionBegin; 4999 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 5000 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5001 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5002 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5003 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5004 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5005 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 5006 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 5007 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 5008 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 5009 /* Caculate size of new SF */ 5010 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5011 if (numRoots < 0) PetscFunctionReturn(0); 5012 for (l = 0; l < numLeaves; ++l) { 5013 const PetscInt p = localPoints[l]; 5014 5015 switch (refiner) { 5016 case 1: 5017 /* Simplicial 2D */ 5018 if ((p >= vStart) && (p < vEnd)) { 5019 /* Old vertices stay the same */ 5020 ++numLeavesNew; 5021 } else if ((p >= fStart) && (p < fEnd)) { 5022 /* Old faces add new faces and vertex */ 5023 numLeavesNew += 2 + 1; 5024 } else if ((p >= cStart) && (p < cEnd)) { 5025 /* Old cells add new cells and interior faces */ 5026 numLeavesNew += 4 + 3; 5027 } 5028 break; 5029 case 2: 5030 /* Hex 2D */ 5031 if ((p >= vStart) && (p < vEnd)) { 5032 /* Old vertices stay the same */ 5033 ++numLeavesNew; 5034 } else if ((p >= fStart) && (p < fEnd)) { 5035 /* Old faces add new faces and vertex */ 5036 numLeavesNew += 2 + 1; 5037 } else if ((p >= cStart) && (p < cEnd)) { 5038 /* Old cells add new cells, interior faces, and vertex */ 5039 numLeavesNew += 4 + 4 + 1; 5040 } 5041 break; 5042 case 5: 5043 /* Simplicial 3D */ 5044 if ((p >= vStart) && (p < vEnd)) { 5045 /* Old vertices stay the same */ 5046 ++numLeavesNew; 5047 } else if ((p >= eStart) && (p < eEnd)) { 5048 /* Old edges add new edges and vertex */ 5049 numLeavesNew += 2 + 1; 5050 } else if ((p >= fStart) && (p < fEnd)) { 5051 /* Old faces add new faces and face edges */ 5052 numLeavesNew += 4 + 3; 5053 } else if ((p >= cStart) && (p < cEnd)) { 5054 /* Old cells add new cells and interior faces and edges */ 5055 numLeavesNew += 8 + 8 + 1; 5056 } 5057 break; 5058 case 7: 5059 /* Hybrid Simplicial 3D */ 5060 if ((p >= vStart) && (p < vEnd)) { 5061 /* Interior vertices stay the same */ 5062 ++numLeavesNew; 5063 } else if ((p >= eStart) && (p < eMax)) { 5064 /* Interior edges add new edges and vertex */ 5065 numLeavesNew += 2 + 1; 5066 } else if ((p >= eMax) && (p < eEnd)) { 5067 /* Hybrid edges stay the same */ 5068 ++numLeavesNew; 5069 } else if ((p >= fStart) && (p < fMax)) { 5070 /* Interior faces add new faces and edges */ 5071 numLeavesNew += 4 + 3; 5072 } else if ((p >= fMax) && (p < fEnd)) { 5073 /* Hybrid faces add new faces and edges */ 5074 numLeavesNew += 2 + 1; 5075 } else if ((p >= cStart) && (p < cMax)) { 5076 /* Interior cells add new cells, faces, and edges */ 5077 numLeavesNew += 8 + 8 + 1; 5078 } else if ((p >= cMax) && (p < cEnd)) { 5079 /* Hybrid cells add new cells and faces */ 5080 numLeavesNew += 4 + 3; 5081 } 5082 break; 5083 case 6: 5084 /* Hex 3D */ 5085 if ((p >= vStart) && (p < vEnd)) { 5086 /* Old vertices stay the same */ 5087 ++numLeavesNew; 5088 } else if ((p >= eStart) && (p < eEnd)) { 5089 /* Old edges add new edges, and vertex */ 5090 numLeavesNew += 2 + 1; 5091 } else if ((p >= fStart) && (p < fEnd)) { 5092 /* Old faces add new faces, edges, and vertex */ 5093 numLeavesNew += 4 + 4 + 1; 5094 } else if ((p >= cStart) && (p < cEnd)) { 5095 /* Old cells add new cells, faces, edges, and vertex */ 5096 numLeavesNew += 8 + 12 + 6 + 1; 5097 } 5098 break; 5099 case 8: 5100 /* Hybrid Hex 3D */ 5101 if ((p >= vStart) && (p < vEnd)) { 5102 /* Old vertices stay the same */ 5103 ++numLeavesNew; 5104 } else if ((p >= eStart) && (p < eMax)) { 5105 /* Interior edges add new edges, and vertex */ 5106 numLeavesNew += 2 + 1; 5107 } else if ((p >= eMax) && (p < eEnd)) { 5108 /* Hybrid edges stay the same */ 5109 ++numLeavesNew; 5110 } else if ((p >= fStart) && (p < fMax)) { 5111 /* Interior faces add new faces, edges, and vertex */ 5112 numLeavesNew += 4 + 4 + 1; 5113 } else if ((p >= fMax) && (p < fEnd)) { 5114 /* Hybrid faces add new faces and edges */ 5115 numLeavesNew += 2 + 1; 5116 } else if ((p >= cStart) && (p < cMax)) { 5117 /* Interior cells add new cells, faces, edges, and vertex */ 5118 numLeavesNew += 8 + 12 + 6 + 1; 5119 } else if ((p >= cStart) && (p < cEnd)) { 5120 /* Hybrid cells add new cells, faces, and edges */ 5121 numLeavesNew += 4 + 4 + 1; 5122 } 5123 break; 5124 default: 5125 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5126 } 5127 } 5128 /* Communicate depthSizes for each remote rank */ 5129 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 5130 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 5131 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 5132 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 5133 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 5134 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 5135 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5136 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5137 for (n = 0; n < numNeighbors; ++n) { 5138 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 5139 } 5140 depthSizeOld[depth] = cMax; 5141 depthSizeOld[0] = vMax; 5142 depthSizeOld[depth-1] = fMax; 5143 depthSizeOld[1] = eMax; 5144 5145 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5146 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5147 5148 depthSizeOld[depth] = cEnd - cStart; 5149 depthSizeOld[0] = vEnd - vStart; 5150 depthSizeOld[depth-1] = fEnd - fStart; 5151 depthSizeOld[1] = eEnd - eStart; 5152 5153 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5154 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5155 for (n = 0; n < numNeighbors; ++n) { 5156 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 5157 } 5158 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 5159 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 5160 /* Calculate new point SF */ 5161 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 5162 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 5163 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 5164 for (l = 0, m = 0; l < numLeaves; ++l) { 5165 PetscInt p = localPoints[l]; 5166 PetscInt rp = remotePoints[l].index, n; 5167 PetscMPIInt rrank = remotePoints[l].rank; 5168 5169 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 5170 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 5171 switch (refiner) { 5172 case 1: 5173 /* Simplicial 2D */ 5174 if ((p >= vStart) && (p < vEnd)) { 5175 /* Old vertices stay the same */ 5176 localPointsNew[m] = vStartNew + (p - vStart); 5177 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5178 remotePointsNew[m].rank = rrank; 5179 ++m; 5180 } else if ((p >= fStart) && (p < fEnd)) { 5181 /* Old faces add new faces and vertex */ 5182 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5183 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5184 remotePointsNew[m].rank = rrank; 5185 ++m; 5186 for (r = 0; r < 2; ++r, ++m) { 5187 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5188 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5189 remotePointsNew[m].rank = rrank; 5190 } 5191 } else if ((p >= cStart) && (p < cEnd)) { 5192 /* Old cells add new cells and interior faces */ 5193 for (r = 0; r < 4; ++r, ++m) { 5194 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5195 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5196 remotePointsNew[m].rank = rrank; 5197 } 5198 for (r = 0; r < 3; ++r, ++m) { 5199 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 5200 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 5201 remotePointsNew[m].rank = rrank; 5202 } 5203 } 5204 break; 5205 case 2: 5206 /* Hex 2D */ 5207 if ((p >= vStart) && (p < vEnd)) { 5208 /* Old vertices stay the same */ 5209 localPointsNew[m] = vStartNew + (p - vStart); 5210 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5211 remotePointsNew[m].rank = rrank; 5212 ++m; 5213 } else if ((p >= fStart) && (p < fEnd)) { 5214 /* Old faces add new faces and vertex */ 5215 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5216 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5217 remotePointsNew[m].rank = rrank; 5218 ++m; 5219 for (r = 0; r < 2; ++r, ++m) { 5220 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5221 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5222 remotePointsNew[m].rank = rrank; 5223 } 5224 } else if ((p >= cStart) && (p < cEnd)) { 5225 /* Old cells add new cells, interior faces, and vertex */ 5226 for (r = 0; r < 4; ++r, ++m) { 5227 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5228 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5229 remotePointsNew[m].rank = rrank; 5230 } 5231 for (r = 0; r < 4; ++r, ++m) { 5232 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 5233 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r; 5234 remotePointsNew[m].rank = rrank; 5235 } 5236 for (r = 0; r < 1; ++r, ++m) { 5237 localPointsNew[m] = vStartNew + (fEnd - fStart) + (p - cStart) + r; 5238 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 5239 remotePointsNew[m].rank = rrank; 5240 } 5241 } 5242 break; 5243 case 3: 5244 /* Hybrid simplicial 2D */ 5245 if ((p >= vStart) && (p < vEnd)) { 5246 /* Old vertices stay the same */ 5247 localPointsNew[m] = vStartNew + (p - vStart); 5248 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5249 remotePointsNew[m].rank = rrank; 5250 ++m; 5251 } else if ((p >= fStart) && (p < fMax)) { 5252 /* Old interior faces add new faces and vertex */ 5253 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5254 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5255 remotePointsNew[m].rank = rrank; 5256 ++m; 5257 for (r = 0; r < 2; ++r, ++m) { 5258 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5259 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5260 remotePointsNew[m].rank = rrank; 5261 } 5262 } else if ((p >= fMax) && (p < fEnd)) { 5263 /* Old hybrid faces stay the same */ 5264 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 5265 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5266 remotePointsNew[m].rank = rrank; 5267 ++m; 5268 } else if ((p >= cStart) && (p < cMax)) { 5269 /* Old interior cells add new cells and interior faces */ 5270 for (r = 0; r < 4; ++r, ++m) { 5271 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5272 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5273 remotePointsNew[m].rank = rrank; 5274 } 5275 for (r = 0; r < 3; ++r, ++m) { 5276 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 5277 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 5278 remotePointsNew[m].rank = rrank; 5279 } 5280 } else if ((p >= cStart) && (p < cMax)) { 5281 /* Old hybrid cells add new cells and hybrid face */ 5282 for (r = 0; r < 2; ++r, ++m) { 5283 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5284 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5285 remotePointsNew[m].rank = rrank; 5286 } 5287 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 5288 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]); 5289 remotePointsNew[m].rank = rrank; 5290 ++m; 5291 } 5292 break; 5293 case 5: 5294 /* Simplicial 3D */ 5295 if ((p >= vStart) && (p < vEnd)) { 5296 /* Old vertices stay the same */ 5297 localPointsNew[m] = vStartNew + (p - vStart); 5298 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5299 remotePointsNew[m].rank = rrank; 5300 ++m; 5301 } else if ((p >= eStart) && (p < eEnd)) { 5302 /* Old edges add new edges and vertex */ 5303 for (r = 0; r < 2; ++r, ++m) { 5304 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5305 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5306 remotePointsNew[m].rank = rrank; 5307 } 5308 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5309 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5310 remotePointsNew[m].rank = rrank; 5311 ++m; 5312 } else if ((p >= fStart) && (p < fEnd)) { 5313 /* Old faces add new faces and face edges */ 5314 for (r = 0; r < 4; ++r, ++m) { 5315 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5316 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5317 remotePointsNew[m].rank = rrank; 5318 } 5319 for (r = 0; r < 3; ++r, ++m) { 5320 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 5321 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*3 + r; 5322 remotePointsNew[m].rank = rrank; 5323 } 5324 } else if ((p >= cStart) && (p < cEnd)) { 5325 /* Old cells add new cells and interior faces and edges */ 5326 for (r = 0; r < 8; ++r, ++m) { 5327 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 5328 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 5329 remotePointsNew[m].rank = rrank; 5330 } 5331 for (r = 0; r < 8; ++r, ++m) { 5332 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 5333 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*8 + r; 5334 remotePointsNew[m].rank = rrank; 5335 } 5336 for (r = 0; r < 1; ++r, ++m) { 5337 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 5338 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*1 + r; 5339 remotePointsNew[m].rank = rrank; 5340 } 5341 } 5342 break; 5343 case 7: 5344 /* Hybrid Simplicial 3D */ 5345 if ((p >= vStart) && (p < vEnd)) { 5346 /* Interior vertices stay the same */ 5347 localPointsNew[m] = vStartNew + (p - vStart); 5348 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5349 remotePointsNew[m].rank = rrank; 5350 ++m; 5351 } else if ((p >= eStart) && (p < eMax)) { 5352 /* Interior edges add new edges and vertex */ 5353 for (r = 0; r < 2; ++r, ++m) { 5354 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5355 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5356 remotePointsNew[m].rank = rrank; 5357 } 5358 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5359 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5360 remotePointsNew[m].rank = rrank; 5361 ++m; 5362 } else if ((p >= eMax) && (p < eEnd)) { 5363 /* Hybrid edges stay the same */ 5364 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 5365 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]); 5366 remotePointsNew[m].rank = rrank; 5367 ++m; 5368 } else if ((p >= fStart) && (p < fMax)) { 5369 /* Interior faces add new faces and edges */ 5370 for (r = 0; r < 4; ++r, ++m) { 5371 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5372 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5373 remotePointsNew[m].rank = rrank; 5374 } 5375 for (r = 0; r < 3; ++r, ++m) { 5376 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 5377 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 5378 remotePointsNew[m].rank = rrank; 5379 } 5380 } else if ((p >= fMax) && (p < fEnd)) { 5381 /* Hybrid faces add new faces and edges */ 5382 for (r = 0; r < 2; ++r, ++m) { 5383 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 5384 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth-1])*2 + r; 5385 remotePointsNew[m].rank = rrank; 5386 } 5387 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 5388 remotePointsNew[m].index = reStartNew[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)+depth-1]); 5389 remotePointsNew[m].rank = rrank; 5390 ++m; 5391 } else if ((p >= cStart) && (p < cMax)) { 5392 /* Interior cells add new cells, faces, and edges */ 5393 for (r = 0; r < 8; ++r, ++m) { 5394 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 5395 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 5396 remotePointsNew[m].rank = rrank; 5397 } 5398 for (r = 0; r < 8; ++r, ++m) { 5399 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 5400 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 5401 remotePointsNew[m].rank = rrank; 5402 } 5403 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + r; 5404 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; 5405 remotePointsNew[m].rank = rrank; 5406 ++m; 5407 } else if ((p >= cMax) && (p < cEnd)) { 5408 /* Hybrid cells add new cells and faces */ 5409 for (r = 0; r < 4; ++r, ++m) { 5410 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 5411 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 5412 remotePointsNew[m].rank = rrank; 5413 } 5414 for (r = 0; r < 3; ++r, ++m) { 5415 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 5416 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])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth])*3 + r; 5417 remotePointsNew[m].rank = rrank; 5418 } 5419 } 5420 break; 5421 case 6: 5422 /* Hex 3D */ 5423 if ((p >= vStart) && (p < vEnd)) { 5424 /* Old vertices stay the same */ 5425 localPointsNew[m] = vStartNew + (p - vStart); 5426 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5427 remotePointsNew[m].rank = rrank; 5428 ++m; 5429 } else if ((p >= eStart) && (p < eEnd)) { 5430 /* Old edges add new edges and vertex */ 5431 for (r = 0; r < 2; ++r, ++m) { 5432 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5433 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5434 remotePointsNew[m].rank = rrank; 5435 } 5436 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5437 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5438 remotePointsNew[m].rank = rrank; 5439 ++m; 5440 } else if ((p >= fStart) && (p < fEnd)) { 5441 /* Old faces add new faces, edges, and vertex */ 5442 for (r = 0; r < 4; ++r, ++m) { 5443 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5444 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5445 remotePointsNew[m].rank = rrank; 5446 } 5447 for (r = 0; r < 4; ++r, ++m) { 5448 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 5449 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*4 + r; 5450 remotePointsNew[m].rank = rrank; 5451 } 5452 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 5453 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]); 5454 remotePointsNew[m].rank = rrank; 5455 ++m; 5456 } else if ((p >= cStart) && (p < cEnd)) { 5457 /* Old cells add new cells, faces, edges, and vertex */ 5458 for (r = 0; r < 8; ++r, ++m) { 5459 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 5460 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 5461 remotePointsNew[m].rank = rrank; 5462 } 5463 for (r = 0; r < 12; ++r, ++m) { 5464 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 5465 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*12 + r; 5466 remotePointsNew[m].rank = rrank; 5467 } 5468 for (r = 0; r < 6; ++r, ++m) { 5469 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 5470 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*6 + r; 5471 remotePointsNew[m].rank = rrank; 5472 } 5473 for (r = 0; r < 1; ++r, ++m) { 5474 localPointsNew[m] = vStartNew + (eEnd - eStart) + (fEnd - fStart) + (p - cStart) + r; 5475 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 5476 remotePointsNew[m].rank = rrank; 5477 } 5478 } 5479 break; 5480 case 8: 5481 /* Hybrid Hex 3D */ 5482 if ((p >= vStart) && (p < vEnd)) { 5483 /* Interior vertices stay the same */ 5484 localPointsNew[m] = vStartNew + (p - vStart); 5485 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5486 remotePointsNew[m].rank = rrank; 5487 ++m; 5488 } else if ((p >= eStart) && (p < eMax)) { 5489 /* Interior edges add new edges and vertex */ 5490 for (r = 0; r < 2; ++r, ++m) { 5491 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5492 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5493 remotePointsNew[m].rank = rrank; 5494 } 5495 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5496 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5497 remotePointsNew[m].rank = rrank; 5498 ++m; 5499 } else if ((p >= eMax) && (p < eEnd)) { 5500 /* Hybrid edges stay the same */ 5501 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 5502 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rp - rdepthMaxOld[n*(depth+1)+1]); 5503 remotePointsNew[m].rank = rrank; 5504 ++m; 5505 } else if ((p >= fStart) && (p < fMax)) { 5506 /* Interior faces add new faces, edges, and vertex */ 5507 for (r = 0; r < 4; ++r, ++m) { 5508 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5509 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5510 remotePointsNew[m].rank = rrank; 5511 } 5512 for (r = 0; r < 4; ++r, ++m) { 5513 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 5514 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 5515 remotePointsNew[m].rank = rrank; 5516 } 5517 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 5518 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 5519 remotePointsNew[m].rank = rrank; 5520 ++m; 5521 } else if ((p >= fMax) && (p < fEnd)) { 5522 /* Hybrid faces add new faces and edges */ 5523 for (r = 0; r < 2; ++r, ++m) { 5524 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 5525 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth-1])*2 + r; 5526 remotePointsNew[m].rank = rrank; 5527 } 5528 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax); 5529 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1]); 5530 remotePointsNew[m].rank = rrank; 5531 ++m; 5532 } else if ((p >= cStart) && (p < cMax)) { 5533 /* Interior cells add new cells, faces, edges, and vertex */ 5534 for (r = 0; r < 8; ++r, ++m) { 5535 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 5536 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 5537 remotePointsNew[m].rank = rrank; 5538 } 5539 for (r = 0; r < 12; ++r, ++m) { 5540 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 5541 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 5542 remotePointsNew[m].rank = rrank; 5543 } 5544 for (r = 0; r < 6; ++r, ++m) { 5545 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 5546 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*6 + r; 5547 remotePointsNew[m].rank = rrank; 5548 } 5549 for (r = 0; r < 1; ++r, ++m) { 5550 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 5551 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 5552 remotePointsNew[m].rank = rrank; 5553 } 5554 } else if ((p >= cMax) && (p < cEnd)) { 5555 /* Hybrid cells add new cells, faces, and edges */ 5556 for (r = 0; r < 4; ++r, ++m) { 5557 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 5558 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 5559 remotePointsNew[m].rank = rrank; 5560 } 5561 for (r = 0; r < 4; ++r, ++m) { 5562 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 5563 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])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 5564 remotePointsNew[m].rank = rrank; 5565 } 5566 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 5567 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1]) + (rp - rdepthMaxOld[n*(depth+1)+depth]); 5568 remotePointsNew[m].rank = rrank; 5569 ++m; 5570 } 5571 break; 5572 default: 5573 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5574 } 5575 } 5576 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew); 5577 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 5578 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 5579 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 5580 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 5581 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 5582 PetscFunctionReturn(0); 5583 } 5584 5585 #undef __FUNCT__ 5586 #define __FUNCT__ "CellRefinerCreateLabels" 5587 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5588 { 5589 PetscInt numLabels, l; 5590 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 5591 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 5592 PetscErrorCode ierr; 5593 5594 PetscFunctionBegin; 5595 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5596 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5597 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5598 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5599 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5600 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 5601 ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 5602 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 5603 switch (refiner) { 5604 case 0: break; 5605 case 7: 5606 case 8: 5607 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 5608 case 3: 5609 case 4: 5610 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 5611 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 5612 } 5613 for (l = 0; l < numLabels; ++l) { 5614 DMLabel label, labelNew; 5615 const char *lname; 5616 PetscBool isDepth; 5617 IS valueIS; 5618 const PetscInt *values; 5619 PetscInt numValues, val; 5620 5621 ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr); 5622 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 5623 if (isDepth) continue; 5624 ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr); 5625 ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr); 5626 ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 5627 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 5628 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 5629 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 5630 for (val = 0; val < numValues; ++val) { 5631 IS pointIS; 5632 const PetscInt *points; 5633 PetscInt numPoints, n; 5634 5635 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 5636 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 5637 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 5638 for (n = 0; n < numPoints; ++n) { 5639 const PetscInt p = points[n]; 5640 switch (refiner) { 5641 case 1: 5642 /* Simplicial 2D */ 5643 if ((p >= vStart) && (p < vEnd)) { 5644 /* Old vertices stay the same */ 5645 newp = vStartNew + (p - vStart); 5646 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5647 } else if ((p >= fStart) && (p < fEnd)) { 5648 /* Old faces add new faces and vertex */ 5649 newp = vStartNew + (vEnd - vStart) + (p - fStart); 5650 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5651 for (r = 0; r < 2; ++r) { 5652 newp = fStartNew + (p - fStart)*2 + r; 5653 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5654 } 5655 } else if ((p >= cStart) && (p < cEnd)) { 5656 /* Old cells add new cells and interior faces */ 5657 for (r = 0; r < 4; ++r) { 5658 newp = cStartNew + (p - cStart)*4 + r; 5659 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5660 } 5661 for (r = 0; r < 3; ++r) { 5662 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 5663 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5664 } 5665 } 5666 break; 5667 case 2: 5668 /* Hex 2D */ 5669 if ((p >= vStart) && (p < vEnd)) { 5670 /* Old vertices stay the same */ 5671 newp = vStartNew + (p - vStart); 5672 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5673 } else if ((p >= fStart) && (p < fEnd)) { 5674 /* Old faces add new faces and vertex */ 5675 newp = vStartNew + (vEnd - vStart) + (p - fStart); 5676 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5677 for (r = 0; r < 2; ++r) { 5678 newp = fStartNew + (p - fStart)*2 + r; 5679 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5680 } 5681 } else if ((p >= cStart) && (p < cEnd)) { 5682 /* Old cells add new cells and interior faces and vertex */ 5683 for (r = 0; r < 4; ++r) { 5684 newp = cStartNew + (p - cStart)*4 + r; 5685 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5686 } 5687 for (r = 0; r < 4; ++r) { 5688 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 5689 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5690 } 5691 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 5692 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5693 } 5694 break; 5695 case 3: 5696 /* Hybrid simplicial 2D */ 5697 if ((p >= vStart) && (p < vEnd)) { 5698 /* Old vertices stay the same */ 5699 newp = vStartNew + (p - vStart); 5700 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5701 } else if ((p >= fStart) && (p < fMax)) { 5702 /* Old interior faces add new faces and vertex */ 5703 newp = vStartNew + (vEnd - vStart) + (p - fStart); 5704 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5705 for (r = 0; r < 2; ++r) { 5706 newp = fStartNew + (p - fStart)*2 + r; 5707 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5708 } 5709 } else if ((p >= fMax) && (p < fEnd)) { 5710 /* Old hybrid faces stay the same */ 5711 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 5712 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5713 } else if ((p >= cStart) && (p < cMax)) { 5714 /* Old interior cells add new cells and interior faces */ 5715 for (r = 0; r < 4; ++r) { 5716 newp = cStartNew + (p - cStart)*4 + r; 5717 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5718 } 5719 for (r = 0; r < 3; ++r) { 5720 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 5721 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5722 } 5723 } else if ((p >= cMax) && (p < cEnd)) { 5724 /* Old hybrid cells add new cells and hybrid face */ 5725 for (r = 0; r < 2; ++r) { 5726 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 5727 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5728 } 5729 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 5730 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5731 } 5732 break; 5733 case 5: 5734 /* Simplicial 3D */ 5735 if ((p >= vStart) && (p < vEnd)) { 5736 /* Old vertices stay the same */ 5737 newp = vStartNew + (p - vStart); 5738 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5739 } else if ((p >= eStart) && (p < eEnd)) { 5740 /* Old edges add new edges and vertex */ 5741 for (r = 0; r < 2; ++r) { 5742 newp = eStartNew + (p - eStart)*2 + r; 5743 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5744 } 5745 newp = vStartNew + (vEnd - vStart) + (p - eStart); 5746 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5747 } else if ((p >= fStart) && (p < fEnd)) { 5748 /* Old faces add new faces and edges */ 5749 for (r = 0; r < 4; ++r) { 5750 newp = fStartNew + (p - fStart)*4 + r; 5751 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5752 } 5753 for (r = 0; r < 3; ++r) { 5754 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 5755 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5756 } 5757 } else if ((p >= cStart) && (p < cEnd)) { 5758 /* Old cells add new cells and interior faces and edges */ 5759 for (r = 0; r < 8; ++r) { 5760 newp = cStartNew + (p - cStart)*8 + r; 5761 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5762 } 5763 for (r = 0; r < 8; ++r) { 5764 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 5765 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5766 } 5767 for (r = 0; r < 1; ++r) { 5768 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 5769 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5770 } 5771 } 5772 break; 5773 case 7: 5774 /* Hybrid Simplicial 3D */ 5775 if ((p >= vStart) && (p < vEnd)) { 5776 /* Interior vertices stay the same */ 5777 newp = vStartNew + (p - vStart); 5778 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5779 } else if ((p >= eStart) && (p < eMax)) { 5780 /* Interior edges add new edges and vertex */ 5781 for (r = 0; r < 2; ++r) { 5782 newp = eStartNew + (p - eStart)*2 + r; 5783 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5784 } 5785 newp = vStartNew + (vEnd - vStart) + (p - eStart); 5786 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5787 } else if ((p >= eMax) && (p < eEnd)) { 5788 /* Hybrid edges stay the same */ 5789 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 5790 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5791 } else if ((p >= fStart) && (p < fMax)) { 5792 /* Interior faces add new faces and edges */ 5793 for (r = 0; r < 4; ++r) { 5794 newp = fStartNew + (p - fStart)*4 + r; 5795 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5796 } 5797 for (r = 0; r < 3; ++r) { 5798 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 5799 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5800 } 5801 } else if ((p >= fMax) && (p < fEnd)) { 5802 /* Hybrid faces add new faces and edges */ 5803 for (r = 0; r < 2; ++r) { 5804 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 5805 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5806 } 5807 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 5808 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5809 } else if ((p >= cStart) && (p < cMax)) { 5810 /* Interior cells add new cells, faces, and edges */ 5811 for (r = 0; r < 8; ++r) { 5812 newp = cStartNew + (p - cStart)*8 + r; 5813 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5814 } 5815 for (r = 0; r < 8; ++r) { 5816 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 5817 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5818 } 5819 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 5820 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5821 } else if ((p >= cMax) && (p < cEnd)) { 5822 /* Hybrid cells add new cells and faces */ 5823 for (r = 0; r < 4; ++r) { 5824 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 5825 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5826 } 5827 for (r = 0; r < 3; ++r) { 5828 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 5829 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5830 } 5831 } 5832 break; 5833 case 6: 5834 /* Hex 3D */ 5835 if ((p >= vStart) && (p < vEnd)) { 5836 /* Old vertices stay the same */ 5837 newp = vStartNew + (p - vStart); 5838 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5839 } else if ((p >= eStart) && (p < eEnd)) { 5840 /* Old edges add new edges and vertex */ 5841 for (r = 0; r < 2; ++r) { 5842 newp = eStartNew + (p - eStart)*2 + r; 5843 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5844 } 5845 newp = vStartNew + (vEnd - vStart) + (p - eStart); 5846 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5847 } else if ((p >= fStart) && (p < fEnd)) { 5848 /* Old faces add new faces, edges, and vertex */ 5849 for (r = 0; r < 4; ++r) { 5850 newp = fStartNew + (p - fStart)*4 + r; 5851 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5852 } 5853 for (r = 0; r < 4; ++r) { 5854 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 5855 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5856 } 5857 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 5858 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5859 } else if ((p >= cStart) && (p < cEnd)) { 5860 /* Old cells add new cells, faces, edges, and vertex */ 5861 for (r = 0; r < 8; ++r) { 5862 newp = cStartNew + (p - cStart)*8 + r; 5863 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5864 } 5865 for (r = 0; r < 12; ++r) { 5866 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 5867 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5868 } 5869 for (r = 0; r < 6; ++r) { 5870 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 5871 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5872 } 5873 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 5874 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5875 } 5876 break; 5877 case 8: 5878 /* Hybrid Hex 3D */ 5879 if ((p >= vStart) && (p < vEnd)) { 5880 /* Interior vertices stay the same */ 5881 newp = vStartNew + (p - vStart); 5882 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5883 } else if ((p >= eStart) && (p < eMax)) { 5884 /* Interior edges add new edges and vertex */ 5885 for (r = 0; r < 2; ++r) { 5886 newp = eStartNew + (p - eStart)*2 + r; 5887 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5888 } 5889 newp = vStartNew + (vEnd - vStart) + (p - eStart); 5890 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5891 } else if ((p >= eMax) && (p < eEnd)) { 5892 /* Hybrid edges stay the same */ 5893 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 5894 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5895 } else if ((p >= fStart) && (p < fMax)) { 5896 /* Interior faces add new faces, edges, and vertex */ 5897 for (r = 0; r < 4; ++r) { 5898 newp = fStartNew + (p - fStart)*4 + r; 5899 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5900 } 5901 for (r = 0; r < 4; ++r) { 5902 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 5903 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5904 } 5905 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 5906 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5907 } else if ((p >= fMax) && (p < fEnd)) { 5908 /* Hybrid faces add new faces and edges */ 5909 for (r = 0; r < 2; ++r) { 5910 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 5911 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5912 } 5913 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 5914 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5915 } else if ((p >= cStart) && (p < cMax)) { 5916 /* Interior cells add new cells, faces, edges, and vertex */ 5917 for (r = 0; r < 8; ++r) { 5918 newp = cStartNew + (p - cStart)*8 + r; 5919 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5920 } 5921 for (r = 0; r < 12; ++r) { 5922 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 5923 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5924 } 5925 for (r = 0; r < 6; ++r) { 5926 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 5927 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5928 } 5929 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 5930 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5931 } else if ((p >= cMax) && (p < cEnd)) { 5932 /* Hybrid cells add new cells, faces, and edges */ 5933 for (r = 0; r < 4; ++r) { 5934 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 5935 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5936 } 5937 for (r = 0; r < 4; ++r) { 5938 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 5939 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5940 } 5941 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 5942 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5943 } 5944 break; 5945 default: 5946 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5947 } 5948 } 5949 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 5950 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 5951 } 5952 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 5953 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 5954 if (0) { 5955 ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr); 5956 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 5957 ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 5958 } 5959 } 5960 PetscFunctionReturn(0); 5961 } 5962 5963 #undef __FUNCT__ 5964 #define __FUNCT__ "DMPlexRefineUniform_Internal" 5965 /* This will only work for interpolated meshes */ 5966 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 5967 { 5968 DM rdm; 5969 PetscInt *depthSize; 5970 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 5971 PetscErrorCode ierr; 5972 5973 PetscFunctionBegin; 5974 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 5975 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 5976 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 5977 ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr); 5978 /* Calculate number of new points of each depth */ 5979 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5980 ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr); 5981 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 5982 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 5983 /* Step 1: Set chart */ 5984 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 5985 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 5986 /* Step 2: Set cone/support sizes */ 5987 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 5988 /* Step 3: Setup refined DM */ 5989 ierr = DMSetUp(rdm);CHKERRQ(ierr); 5990 /* Step 4: Set cones and supports */ 5991 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 5992 /* Step 5: Stratify */ 5993 ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 5994 /* Step 6: Set coordinates for vertices */ 5995 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 5996 /* Step 7: Create pointSF */ 5997 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 5998 /* Step 8: Create labels */ 5999 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6000 ierr = PetscFree(depthSize);CHKERRQ(ierr); 6001 6002 *dmRefined = rdm; 6003 PetscFunctionReturn(0); 6004 } 6005 6006 #undef __FUNCT__ 6007 #define __FUNCT__ "DMPlexSetRefinementUniform" 6008 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 6009 { 6010 DM_Plex *mesh = (DM_Plex*) dm->data; 6011 6012 PetscFunctionBegin; 6013 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6014 mesh->refinementUniform = refinementUniform; 6015 PetscFunctionReturn(0); 6016 } 6017 6018 #undef __FUNCT__ 6019 #define __FUNCT__ "DMPlexGetRefinementUniform" 6020 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 6021 { 6022 DM_Plex *mesh = (DM_Plex*) dm->data; 6023 6024 PetscFunctionBegin; 6025 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6026 PetscValidPointer(refinementUniform, 2); 6027 *refinementUniform = mesh->refinementUniform; 6028 PetscFunctionReturn(0); 6029 } 6030 6031 #undef __FUNCT__ 6032 #define __FUNCT__ "DMPlexSetRefinementLimit" 6033 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 6034 { 6035 DM_Plex *mesh = (DM_Plex*) dm->data; 6036 6037 PetscFunctionBegin; 6038 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6039 mesh->refinementLimit = refinementLimit; 6040 PetscFunctionReturn(0); 6041 } 6042 6043 #undef __FUNCT__ 6044 #define __FUNCT__ "DMPlexGetRefinementLimit" 6045 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 6046 { 6047 DM_Plex *mesh = (DM_Plex*) dm->data; 6048 6049 PetscFunctionBegin; 6050 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6051 PetscValidPointer(refinementLimit, 2); 6052 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 6053 *refinementLimit = mesh->refinementLimit; 6054 PetscFunctionReturn(0); 6055 } 6056 6057 #undef __FUNCT__ 6058 #define __FUNCT__ "DMPlexGetCellRefiner_Internal" 6059 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 6060 { 6061 PetscInt dim, cStart, cEnd, coneSize, cMax; 6062 PetscErrorCode ierr; 6063 6064 PetscFunctionBegin; 6065 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 6066 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6067 if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);} 6068 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 6069 ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 6070 switch (dim) { 6071 case 2: 6072 switch (coneSize) { 6073 case 3: 6074 if (cMax >= 0) *cellRefiner = 3; /* Hybrid */ 6075 else *cellRefiner = 1; /* Triangular */ 6076 break; 6077 case 4: 6078 if (cMax >= 0) *cellRefiner = 4; /* Hybrid */ 6079 else *cellRefiner = 2; /* Quadrilateral */ 6080 break; 6081 default: 6082 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6083 } 6084 break; 6085 case 3: 6086 switch (coneSize) { 6087 case 4: 6088 if (cMax >= 0) *cellRefiner = 7; /* Hybrid */ 6089 else *cellRefiner = 5; /* Tetrahedral */ 6090 break; 6091 case 6: 6092 if (cMax >= 0) *cellRefiner = 8; /* Hybrid */ 6093 else *cellRefiner = 6; /* hexahedral */ 6094 break; 6095 default: 6096 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6097 } 6098 break; 6099 default: 6100 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 6101 } 6102 PetscFunctionReturn(0); 6103 } 6104