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