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