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