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 case 8: /* Hybrid Hex 3D */ 3757 /* Face vertices have the average of corner coordinates */ 3758 for (f = fStart; f < fMax; ++f) { 3759 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 3760 PetscInt *cone = NULL; 3761 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 3762 3763 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3764 for (p = 0; p < closureSize*2; p += 2) { 3765 const PetscInt point = cone[p]; 3766 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 3767 } 3768 for (v = 0; v < coneSize; ++v) { 3769 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 3770 } 3771 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3772 for (d = 0; d < dim; ++d) { 3773 coordsNew[offnew+d] = 0.0; 3774 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 3775 coordsNew[offnew+d] /= coneSize; 3776 } 3777 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3778 } 3779 case 2: /* Hex 2D */ 3780 /* Cell vertices have the average of corner coordinates */ 3781 for (c = cStart; c < cEnd; ++c) { 3782 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (c - cStart) + (dim > 2 ? (fEnd - fStart) : 0); 3783 PetscInt *cone = NULL; 3784 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 3785 3786 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3787 for (p = 0; p < closureSize*2; p += 2) { 3788 const PetscInt point = cone[p]; 3789 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 3790 } 3791 for (v = 0; v < coneSize; ++v) { 3792 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 3793 } 3794 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3795 for (d = 0; d < dim; ++d) { 3796 coordsNew[offnew+d] = 0.0; 3797 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 3798 coordsNew[offnew+d] /= coneSize; 3799 } 3800 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3801 } 3802 case 1: /* Simplicial 2D */ 3803 case 3: /* Hybrid Simplicial 2D */ 3804 case 5: /* Simplicial 3D */ 3805 case 7: /* Hybrid Simplicial 3D */ 3806 /* Edge vertices have the average of endpoint coordinates */ 3807 for (e = eStart; e < eMax; ++e) { 3808 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3809 const PetscInt *cone; 3810 PetscInt coneSize, offA, offB, offnew, d; 3811 3812 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 3813 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 3814 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3815 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 3816 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 3817 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3818 for (d = 0; d < dim; ++d) { 3819 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]); 3820 } 3821 } 3822 /* Old vertices have the same coordinates */ 3823 for (v = vStart; v < vEnd; ++v) { 3824 const PetscInt newv = vStartNew + (v - vStart); 3825 PetscInt off, offnew, d; 3826 3827 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 3828 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3829 for (d = 0; d < dim; ++d) { 3830 coordsNew[offnew+d] = coords[off+d]; 3831 } 3832 } 3833 break; 3834 default: 3835 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 3836 } 3837 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 3838 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 3839 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 3840 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 3841 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 3842 PetscFunctionReturn(0); 3843 } 3844 3845 #undef __FUNCT__ 3846 #define __FUNCT__ "DMPlexCreateProcessSF" 3847 static PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 3848 { 3849 PetscInt numRoots, numLeaves, l; 3850 const PetscInt *localPoints; 3851 const PetscSFNode *remotePoints; 3852 PetscInt *localPointsNew; 3853 PetscSFNode *remotePointsNew; 3854 PetscInt *ranks, *ranksNew; 3855 PetscErrorCode ierr; 3856 3857 PetscFunctionBegin; 3858 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 3859 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 3860 for (l = 0; l < numLeaves; ++l) { 3861 ranks[l] = remotePoints[l].rank; 3862 } 3863 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 3864 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 3865 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 3866 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 3867 for (l = 0; l < numLeaves; ++l) { 3868 ranksNew[l] = ranks[l]; 3869 localPointsNew[l] = l; 3870 remotePointsNew[l].index = 0; 3871 remotePointsNew[l].rank = ranksNew[l]; 3872 } 3873 ierr = PetscFree(ranks);CHKERRQ(ierr); 3874 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr); 3875 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 3876 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 3877 ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 3878 PetscFunctionReturn(0); 3879 } 3880 3881 #undef __FUNCT__ 3882 #define __FUNCT__ "CellRefinerCreateSF" 3883 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 3884 { 3885 PetscSF sf, sfNew, sfProcess; 3886 IS processRanks; 3887 MPI_Datatype depthType; 3888 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 3889 const PetscInt *localPoints, *neighbors; 3890 const PetscSFNode *remotePoints; 3891 PetscInt *localPointsNew; 3892 PetscSFNode *remotePointsNew; 3893 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 3894 PetscInt depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 3895 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 3896 PetscErrorCode ierr; 3897 3898 PetscFunctionBegin; 3899 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 3900 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3901 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 3902 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 3903 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 3904 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 3905 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 3906 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 3907 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 3908 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 3909 /* Caculate size of new SF */ 3910 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 3911 if (numRoots < 0) PetscFunctionReturn(0); 3912 for (l = 0; l < numLeaves; ++l) { 3913 const PetscInt p = localPoints[l]; 3914 3915 switch (refiner) { 3916 case 1: 3917 /* Simplicial 2D */ 3918 if ((p >= vStart) && (p < vEnd)) { 3919 /* Old vertices stay the same */ 3920 ++numLeavesNew; 3921 } else if ((p >= fStart) && (p < fEnd)) { 3922 /* Old faces add new faces and vertex */ 3923 numLeavesNew += 2 + 1; 3924 } else if ((p >= cStart) && (p < cEnd)) { 3925 /* Old cells add new cells and interior faces */ 3926 numLeavesNew += 4 + 3; 3927 } 3928 break; 3929 case 2: 3930 /* Hex 2D */ 3931 if ((p >= vStart) && (p < vEnd)) { 3932 /* Old vertices stay the same */ 3933 ++numLeavesNew; 3934 } else if ((p >= fStart) && (p < fEnd)) { 3935 /* Old faces add new faces and vertex */ 3936 numLeavesNew += 2 + 1; 3937 } else if ((p >= cStart) && (p < cEnd)) { 3938 /* Old cells add new cells, interior faces, and vertex */ 3939 numLeavesNew += 4 + 4 + 1; 3940 } 3941 break; 3942 case 5: 3943 /* Simplicial 3D */ 3944 if ((p >= vStart) && (p < vEnd)) { 3945 /* Old vertices stay the same */ 3946 ++numLeavesNew; 3947 } else if ((p >= eStart) && (p < eEnd)) { 3948 /* Old edges add new edges and vertex */ 3949 numLeavesNew += 2 + 1; 3950 } else if ((p >= fStart) && (p < fEnd)) { 3951 /* Old faces add new faces and face edges */ 3952 numLeavesNew += 4 + 3; 3953 } else if ((p >= cStart) && (p < cEnd)) { 3954 /* Old cells add new cells and interior faces and edges */ 3955 numLeavesNew += 8 + 8 + 1; 3956 } 3957 break; 3958 case 7: 3959 /* Hybrid Simplicial 3D */ 3960 if ((p >= vStart) && (p < vEnd)) { 3961 /* Interior vertices stay the same */ 3962 ++numLeavesNew; 3963 } else if ((p >= eStart) && (p < eMax)) { 3964 /* Interior edges add new edges and vertex */ 3965 numLeavesNew += 2 + 1; 3966 } else if ((p >= eMax) && (p < eEnd)) { 3967 /* Hybrid edges stay the same */ 3968 ++numLeavesNew; 3969 } else if ((p >= fStart) && (p < fMax)) { 3970 /* Interior faces add new faces and edges */ 3971 numLeavesNew += 4 + 3; 3972 } else if ((p >= fMax) && (p < fEnd)) { 3973 /* Hybrid faces add new faces and edges */ 3974 numLeavesNew += 2 + 1; 3975 } else if ((p >= cStart) && (p < cMax)) { 3976 /* Interior cells add new cells, faces, and edges */ 3977 numLeavesNew += 8 + 8 + 1; 3978 } else if ((p >= cMax) && (p < cEnd)) { 3979 /* Hybrid cells add new cells and faces */ 3980 numLeavesNew += 4 + 3; 3981 } 3982 break; 3983 case 6: 3984 /* Hex 3D */ 3985 if ((p >= vStart) && (p < vEnd)) { 3986 /* Old vertices stay the same */ 3987 ++numLeavesNew; 3988 } else if ((p >= eStart) && (p < eEnd)) { 3989 /* Old edges add new edges, and vertex */ 3990 numLeavesNew += 2 + 1; 3991 } else if ((p >= fStart) && (p < fEnd)) { 3992 /* Old faces add new faces, edges, and vertex */ 3993 numLeavesNew += 4 + 4 + 1; 3994 } else if ((p >= cStart) && (p < cEnd)) { 3995 /* Old cells add new cells, faces, edges, and vertex */ 3996 numLeavesNew += 8 + 12 + 6 + 1; 3997 } 3998 break; 3999 default: 4000 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 4001 } 4002 } 4003 /* Communicate depthSizes for each remote rank */ 4004 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 4005 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 4006 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 4007 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 4008 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 4009 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 4010 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 4011 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 4012 for (n = 0; n < numNeighbors; ++n) { 4013 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 4014 } 4015 depthSizeOld[depth] = cMax; 4016 depthSizeOld[0] = vMax; 4017 depthSizeOld[depth-1] = fMax; 4018 depthSizeOld[1] = eMax; 4019 4020 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 4021 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 4022 4023 depthSizeOld[depth] = cEnd - cStart; 4024 depthSizeOld[0] = vEnd - vStart; 4025 depthSizeOld[depth-1] = fEnd - fStart; 4026 depthSizeOld[1] = eEnd - eStart; 4027 4028 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 4029 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 4030 for (n = 0; n < numNeighbors; ++n) { 4031 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 4032 } 4033 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 4034 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 4035 /* Calculate new point SF */ 4036 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 4037 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 4038 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 4039 for (l = 0, m = 0; l < numLeaves; ++l) { 4040 PetscInt p = localPoints[l]; 4041 PetscInt rp = remotePoints[l].index, n; 4042 PetscMPIInt rrank = remotePoints[l].rank; 4043 4044 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 4045 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 4046 switch (refiner) { 4047 case 1: 4048 /* Simplicial 2D */ 4049 if ((p >= vStart) && (p < vEnd)) { 4050 /* Old vertices stay the same */ 4051 localPointsNew[m] = vStartNew + (p - vStart); 4052 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4053 remotePointsNew[m].rank = rrank; 4054 ++m; 4055 } else if ((p >= fStart) && (p < fEnd)) { 4056 /* Old faces add new faces and vertex */ 4057 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 4058 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 4059 remotePointsNew[m].rank = rrank; 4060 ++m; 4061 for (r = 0; r < 2; ++r, ++m) { 4062 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 4063 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 4064 remotePointsNew[m].rank = rrank; 4065 } 4066 } else if ((p >= cStart) && (p < cEnd)) { 4067 /* Old cells add new cells and interior faces */ 4068 for (r = 0; r < 4; ++r, ++m) { 4069 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4070 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4071 remotePointsNew[m].rank = rrank; 4072 } 4073 for (r = 0; r < 3; ++r, ++m) { 4074 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 4075 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 4076 remotePointsNew[m].rank = rrank; 4077 } 4078 } 4079 break; 4080 case 2: 4081 /* Hex 2D */ 4082 if ((p >= vStart) && (p < vEnd)) { 4083 /* Old vertices stay the same */ 4084 localPointsNew[m] = vStartNew + (p - vStart); 4085 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4086 remotePointsNew[m].rank = rrank; 4087 ++m; 4088 } else if ((p >= fStart) && (p < fEnd)) { 4089 /* Old faces add new faces and vertex */ 4090 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 4091 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 4092 remotePointsNew[m].rank = rrank; 4093 ++m; 4094 for (r = 0; r < 2; ++r, ++m) { 4095 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 4096 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 4097 remotePointsNew[m].rank = rrank; 4098 } 4099 } else if ((p >= cStart) && (p < cEnd)) { 4100 /* Old cells add new cells, interior faces, and vertex */ 4101 for (r = 0; r < 4; ++r, ++m) { 4102 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4103 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4104 remotePointsNew[m].rank = rrank; 4105 } 4106 for (r = 0; r < 4; ++r, ++m) { 4107 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 4108 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r; 4109 remotePointsNew[m].rank = rrank; 4110 } 4111 for (r = 0; r < 1; ++r, ++m) { 4112 localPointsNew[m] = vStartNew + (fEnd - fStart) + (p - cStart) + r; 4113 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 4114 remotePointsNew[m].rank = rrank; 4115 } 4116 } 4117 break; 4118 case 3: 4119 /* Hybrid simplicial 2D */ 4120 if ((p >= vStart) && (p < vEnd)) { 4121 /* Old vertices stay the same */ 4122 localPointsNew[m] = vStartNew + (p - vStart); 4123 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4124 remotePointsNew[m].rank = rrank; 4125 ++m; 4126 } else if ((p >= fStart) && (p < fMax)) { 4127 /* Old interior faces add new faces and vertex */ 4128 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 4129 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 4130 remotePointsNew[m].rank = rrank; 4131 ++m; 4132 for (r = 0; r < 2; ++r, ++m) { 4133 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 4134 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 4135 remotePointsNew[m].rank = rrank; 4136 } 4137 } else if ((p >= fMax) && (p < fEnd)) { 4138 /* Old hybrid faces stay the same */ 4139 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 4140 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 4141 remotePointsNew[m].rank = rrank; 4142 ++m; 4143 } else if ((p >= cStart) && (p < cMax)) { 4144 /* Old interior cells add new cells and interior faces */ 4145 for (r = 0; r < 4; ++r, ++m) { 4146 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4147 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4148 remotePointsNew[m].rank = rrank; 4149 } 4150 for (r = 0; r < 3; ++r, ++m) { 4151 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 4152 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 4153 remotePointsNew[m].rank = rrank; 4154 } 4155 } else if ((p >= cStart) && (p < cMax)) { 4156 /* Old hybrid cells add new cells and hybrid face */ 4157 for (r = 0; r < 2; ++r, ++m) { 4158 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4159 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4160 remotePointsNew[m].rank = rrank; 4161 } 4162 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 4163 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]); 4164 remotePointsNew[m].rank = rrank; 4165 ++m; 4166 } 4167 break; 4168 case 5: 4169 /* Simplicial 3D */ 4170 if ((p >= vStart) && (p < vEnd)) { 4171 /* Old vertices stay the same */ 4172 localPointsNew[m] = vStartNew + (p - vStart); 4173 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4174 remotePointsNew[m].rank = rrank; 4175 ++m; 4176 } else if ((p >= eStart) && (p < eEnd)) { 4177 /* Old edges add new edges and vertex */ 4178 for (r = 0; r < 2; ++r, ++m) { 4179 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 4180 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 4181 remotePointsNew[m].rank = rrank; 4182 } 4183 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 4184 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 4185 remotePointsNew[m].rank = rrank; 4186 ++m; 4187 } else if ((p >= fStart) && (p < fEnd)) { 4188 /* Old faces add new faces and face edges */ 4189 for (r = 0; r < 4; ++r, ++m) { 4190 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 4191 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 4192 remotePointsNew[m].rank = rrank; 4193 } 4194 for (r = 0; r < 3; ++r, ++m) { 4195 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 4196 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*3 + r; 4197 remotePointsNew[m].rank = rrank; 4198 } 4199 } else if ((p >= cStart) && (p < cEnd)) { 4200 /* Old cells add new cells and interior faces and edges */ 4201 for (r = 0; r < 8; ++r, ++m) { 4202 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 4203 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 4204 remotePointsNew[m].rank = rrank; 4205 } 4206 for (r = 0; r < 8; ++r, ++m) { 4207 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 4208 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*8 + r; 4209 remotePointsNew[m].rank = rrank; 4210 } 4211 for (r = 0; r < 1; ++r, ++m) { 4212 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 4213 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*1 + r; 4214 remotePointsNew[m].rank = rrank; 4215 } 4216 } 4217 break; 4218 case 7: 4219 /* Hybrid Simplicial 3D */ 4220 if ((p >= vStart) && (p < vEnd)) { 4221 /* Interior vertices stay the same */ 4222 localPointsNew[m] = vStartNew + (p - vStart); 4223 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4224 remotePointsNew[m].rank = rrank; 4225 ++m; 4226 } else if ((p >= eStart) && (p < eMax)) { 4227 /* Interior edges add new edges and vertex */ 4228 for (r = 0; r < 2; ++r, ++m) { 4229 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 4230 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 4231 remotePointsNew[m].rank = rrank; 4232 } 4233 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 4234 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 4235 remotePointsNew[m].rank = rrank; 4236 ++m; 4237 } else if ((p >= eMax) && (p < eEnd)) { 4238 /* Hybrid edges stay the same */ 4239 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 4240 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]); 4241 remotePointsNew[m].rank = rrank; 4242 ++m; 4243 } else if ((p >= fStart) && (p < fMax)) { 4244 /* Interior faces add new faces and edges */ 4245 for (r = 0; r < 4; ++r, ++m) { 4246 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 4247 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 4248 remotePointsNew[m].rank = rrank; 4249 } 4250 for (r = 0; r < 3; ++r, ++m) { 4251 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 4252 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 4253 remotePointsNew[m].rank = rrank; 4254 } 4255 } else if ((p >= fMax) && (p < fEnd)) { 4256 /* Hybrid faces add new faces and edges */ 4257 for (r = 0; r < 2; ++r, ++m) { 4258 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fStart)*2 + r; 4259 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; 4260 remotePointsNew[m].rank = rrank; 4261 } 4262 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart) + (cMax - cStart) + (fEnd - fMax); 4263 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]); 4264 remotePointsNew[m].rank = rrank; 4265 ++m; 4266 } else if ((p >= cStart) && (p < cMax)) { 4267 /* Interior cells add new cells, faces, and edges */ 4268 for (r = 0; r < 8; ++r, ++m) { 4269 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 4270 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 4271 remotePointsNew[m].rank = rrank; 4272 } 4273 for (r = 0; r < 8; ++r, ++m) { 4274 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 4275 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 4276 remotePointsNew[m].rank = rrank; 4277 } 4278 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + r; 4279 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; 4280 remotePointsNew[m].rank = rrank; 4281 ++m; 4282 } else if ((p >= cMax) && (p < cEnd)) { 4283 /* Hybrid cells add new cells and faces */ 4284 for (r = 0; r < 4; ++r, ++m) { 4285 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 4286 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 4287 remotePointsNew[m].rank = rrank; 4288 } 4289 for (r = 0; r < 3; ++r, ++m) { 4290 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*4 + (p - cMax)*3 + r; 4291 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; 4292 remotePointsNew[m].rank = rrank; 4293 } 4294 } 4295 break; 4296 case 6: 4297 /* Hex 3D */ 4298 if ((p >= vStart) && (p < vEnd)) { 4299 /* Old vertices stay the same */ 4300 localPointsNew[m] = vStartNew + (p - vStart); 4301 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4302 remotePointsNew[m].rank = rrank; 4303 ++m; 4304 } else if ((p >= eStart) && (p < eEnd)) { 4305 /* Old edges add new edges and vertex */ 4306 for (r = 0; r < 2; ++r, ++m) { 4307 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 4308 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 4309 remotePointsNew[m].rank = rrank; 4310 } 4311 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 4312 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 4313 remotePointsNew[m].rank = rrank; 4314 ++m; 4315 } else if ((p >= fStart) && (p < fEnd)) { 4316 /* Old faces add new faces, edges, and vertex */ 4317 for (r = 0; r < 4; ++r, ++m) { 4318 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 4319 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 4320 remotePointsNew[m].rank = rrank; 4321 } 4322 for (r = 0; r < 4; ++r, ++m) { 4323 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 4324 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*4 + r; 4325 remotePointsNew[m].rank = rrank; 4326 } 4327 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 4328 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]); 4329 remotePointsNew[m].rank = rrank; 4330 ++m; 4331 } else if ((p >= cStart) && (p < cEnd)) { 4332 /* Old cells add new cells, faces, edges, and vertex */ 4333 for (r = 0; r < 8; ++r, ++m) { 4334 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 4335 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 4336 remotePointsNew[m].rank = rrank; 4337 } 4338 for (r = 0; r < 12; ++r, ++m) { 4339 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 4340 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*12 + r; 4341 remotePointsNew[m].rank = rrank; 4342 } 4343 for (r = 0; r < 6; ++r, ++m) { 4344 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 4345 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*6 + r; 4346 remotePointsNew[m].rank = rrank; 4347 } 4348 for (r = 0; r < 1; ++r, ++m) { 4349 localPointsNew[m] = vStartNew + (eEnd - eStart) + (fEnd - fStart) + (p - cStart) + r; 4350 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 4351 remotePointsNew[m].rank = rrank; 4352 } 4353 } 4354 break; 4355 default: 4356 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 4357 } 4358 } 4359 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew); 4360 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 4361 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 4362 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 4363 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 4364 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 4365 PetscFunctionReturn(0); 4366 } 4367 4368 #undef __FUNCT__ 4369 #define __FUNCT__ "CellRefinerCreateLabels" 4370 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 4371 { 4372 PetscInt numLabels, l; 4373 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 4374 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 4375 PetscErrorCode ierr; 4376 4377 PetscFunctionBegin; 4378 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 4379 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 4380 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 4381 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 4382 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 4383 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 4384 ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 4385 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 4386 switch (refiner) { 4387 case 0: break; 4388 case 7: 4389 case 8: 4390 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 4391 case 3: 4392 case 4: 4393 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 4394 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 4395 } 4396 for (l = 0; l < numLabels; ++l) { 4397 DMLabel label, labelNew; 4398 const char *lname; 4399 PetscBool isDepth; 4400 IS valueIS; 4401 const PetscInt *values; 4402 PetscInt numValues, val; 4403 4404 ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr); 4405 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 4406 if (isDepth) continue; 4407 ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr); 4408 ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr); 4409 ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 4410 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 4411 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 4412 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 4413 for (val = 0; val < numValues; ++val) { 4414 IS pointIS; 4415 const PetscInt *points; 4416 PetscInt numPoints, n; 4417 4418 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 4419 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 4420 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 4421 for (n = 0; n < numPoints; ++n) { 4422 const PetscInt p = points[n]; 4423 switch (refiner) { 4424 case 1: 4425 /* Simplicial 2D */ 4426 if ((p >= vStart) && (p < vEnd)) { 4427 /* Old vertices stay the same */ 4428 newp = vStartNew + (p - vStart); 4429 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4430 } else if ((p >= fStart) && (p < fEnd)) { 4431 /* Old faces add new faces and vertex */ 4432 newp = vStartNew + (vEnd - vStart) + (p - fStart); 4433 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4434 for (r = 0; r < 2; ++r) { 4435 newp = fStartNew + (p - fStart)*2 + r; 4436 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4437 } 4438 } else if ((p >= cStart) && (p < cEnd)) { 4439 /* Old cells add new cells and interior faces */ 4440 for (r = 0; r < 4; ++r) { 4441 newp = cStartNew + (p - cStart)*4 + r; 4442 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4443 } 4444 for (r = 0; r < 3; ++r) { 4445 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 4446 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4447 } 4448 } 4449 break; 4450 case 2: 4451 /* Hex 2D */ 4452 if ((p >= vStart) && (p < vEnd)) { 4453 /* Old vertices stay the same */ 4454 newp = vStartNew + (p - vStart); 4455 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4456 } else if ((p >= fStart) && (p < fEnd)) { 4457 /* Old faces add new faces and vertex */ 4458 newp = vStartNew + (vEnd - vStart) + (p - fStart); 4459 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4460 for (r = 0; r < 2; ++r) { 4461 newp = fStartNew + (p - fStart)*2 + r; 4462 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4463 } 4464 } else if ((p >= cStart) && (p < cEnd)) { 4465 /* Old cells add new cells and interior faces and vertex */ 4466 for (r = 0; r < 4; ++r) { 4467 newp = cStartNew + (p - cStart)*4 + r; 4468 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4469 } 4470 for (r = 0; r < 4; ++r) { 4471 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 4472 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4473 } 4474 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 4475 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4476 } 4477 break; 4478 case 3: 4479 /* Hybrid simplicial 2D */ 4480 if ((p >= vStart) && (p < vEnd)) { 4481 /* Old vertices stay the same */ 4482 newp = vStartNew + (p - vStart); 4483 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4484 } else if ((p >= fStart) && (p < fMax)) { 4485 /* Old interior faces add new faces and vertex */ 4486 newp = vStartNew + (vEnd - vStart) + (p - fStart); 4487 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4488 for (r = 0; r < 2; ++r) { 4489 newp = fStartNew + (p - fStart)*2 + r; 4490 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4491 } 4492 } else if ((p >= fMax) && (p < fEnd)) { 4493 /* Old hybrid faces stay the same */ 4494 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 4495 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4496 } else if ((p >= cStart) && (p < cMax)) { 4497 /* Old interior cells add new cells and interior faces */ 4498 for (r = 0; r < 4; ++r) { 4499 newp = cStartNew + (p - cStart)*4 + r; 4500 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4501 } 4502 for (r = 0; r < 3; ++r) { 4503 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 4504 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4505 } 4506 } else if ((p >= cMax) && (p < cEnd)) { 4507 /* Old hybrid cells add new cells and hybrid face */ 4508 for (r = 0; r < 2; ++r) { 4509 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 4510 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4511 } 4512 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 4513 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4514 } 4515 break; 4516 case 5: 4517 /* Simplicial 3D */ 4518 if ((p >= vStart) && (p < vEnd)) { 4519 /* Old vertices stay the same */ 4520 newp = vStartNew + (p - vStart); 4521 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4522 } else if ((p >= eStart) && (p < eEnd)) { 4523 /* Old edges add new edges and vertex */ 4524 for (r = 0; r < 2; ++r) { 4525 newp = eStartNew + (p - eStart)*2 + r; 4526 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4527 } 4528 newp = vStartNew + (vEnd - vStart) + (p - eStart); 4529 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4530 } else if ((p >= fStart) && (p < fEnd)) { 4531 /* Old faces add new faces and edges */ 4532 for (r = 0; r < 4; ++r) { 4533 newp = fStartNew + (p - fStart)*4 + r; 4534 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4535 } 4536 for (r = 0; r < 3; ++r) { 4537 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 4538 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4539 } 4540 } else if ((p >= cStart) && (p < cEnd)) { 4541 /* Old cells add new cells and interior faces and edges */ 4542 for (r = 0; r < 8; ++r) { 4543 newp = cStartNew + (p - cStart)*8 + r; 4544 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4545 } 4546 for (r = 0; r < 8; ++r) { 4547 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 4548 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4549 } 4550 for (r = 0; r < 1; ++r) { 4551 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 4552 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4553 } 4554 } 4555 break; 4556 case 7: 4557 /* Hybrid Simplicial 3D */ 4558 if ((p >= vStart) && (p < vEnd)) { 4559 /* Interior vertices stay the same */ 4560 newp = vStartNew + (p - vStart); 4561 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4562 } else if ((p >= eStart) && (p < eMax)) { 4563 /* Interior edges add new edges and vertex */ 4564 for (r = 0; r < 2; ++r) { 4565 newp = eStartNew + (p - eStart)*2 + r; 4566 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4567 } 4568 newp = vStartNew + (vEnd - vStart) + (p - eStart); 4569 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4570 } else if ((p >= eMax) && (p < eEnd)) { 4571 /* Hybrid edges stay the same */ 4572 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 4573 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4574 } else if ((p >= fStart) && (p < fMax)) { 4575 /* Interior faces add new faces and edges */ 4576 for (r = 0; r < 4; ++r) { 4577 newp = fStartNew + (p - fStart)*4 + r; 4578 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4579 } 4580 for (r = 0; r < 3; ++r) { 4581 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 4582 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4583 } 4584 } else if ((p >= fMax) && (p < fEnd)) { 4585 /* Hybrid faces add new faces and edges */ 4586 for (r = 0; r < 2; ++r) { 4587 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 4588 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4589 } 4590 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 4591 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4592 } else if ((p >= cStart) && (p < cMax)) { 4593 /* Interior cells add new cells, faces, and edges */ 4594 for (r = 0; r < 8; ++r) { 4595 newp = cStartNew + (p - cStart)*8 + r; 4596 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4597 } 4598 for (r = 0; r < 8; ++r) { 4599 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 4600 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4601 } 4602 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 4603 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4604 } else if ((p >= cMax) && (p < cEnd)) { 4605 /* Hybrid cells add new cells and faces */ 4606 for (r = 0; r < 4; ++r) { 4607 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 4608 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4609 } 4610 for (r = 0; r < 3; ++r) { 4611 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 4612 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4613 } 4614 } 4615 break; 4616 case 6: 4617 /* Hex 3D */ 4618 if ((p >= vStart) && (p < vEnd)) { 4619 /* Old vertices stay the same */ 4620 newp = vStartNew + (p - vStart); 4621 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4622 } else if ((p >= eStart) && (p < eEnd)) { 4623 /* Old edges add new edges and vertex */ 4624 for (r = 0; r < 2; ++r) { 4625 newp = eStartNew + (p - eStart)*2 + r; 4626 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4627 } 4628 newp = vStartNew + (vEnd - vStart) + (p - eStart); 4629 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4630 } else if ((p >= fStart) && (p < fEnd)) { 4631 /* Old faces add new faces, edges, and vertex */ 4632 for (r = 0; r < 4; ++r) { 4633 newp = fStartNew + (p - fStart)*4 + r; 4634 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4635 } 4636 for (r = 0; r < 4; ++r) { 4637 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 4638 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4639 } 4640 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 4641 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4642 } else if ((p >= cStart) && (p < cEnd)) { 4643 /* Old cells add new cells, faces, edges, and vertex */ 4644 for (r = 0; r < 8; ++r) { 4645 newp = cStartNew + (p - cStart)*8 + r; 4646 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4647 } 4648 for (r = 0; r < 12; ++r) { 4649 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 4650 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4651 } 4652 for (r = 0; r < 6; ++r) { 4653 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 4654 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4655 } 4656 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 4657 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4658 } 4659 break; 4660 default: 4661 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 4662 } 4663 } 4664 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 4665 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 4666 } 4667 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 4668 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 4669 if (0) { 4670 ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr); 4671 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 4672 ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 4673 } 4674 } 4675 PetscFunctionReturn(0); 4676 } 4677 4678 #undef __FUNCT__ 4679 #define __FUNCT__ "DMPlexRefineUniform_Internal" 4680 /* This will only work for interpolated meshes */ 4681 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 4682 { 4683 DM rdm; 4684 PetscInt *depthSize; 4685 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 4686 PetscErrorCode ierr; 4687 4688 PetscFunctionBegin; 4689 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 4690 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 4691 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 4692 ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr); 4693 /* Calculate number of new points of each depth */ 4694 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 4695 ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr); 4696 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 4697 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 4698 /* Step 1: Set chart */ 4699 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 4700 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 4701 /* Step 2: Set cone/support sizes */ 4702 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4703 /* Step 3: Setup refined DM */ 4704 ierr = DMSetUp(rdm);CHKERRQ(ierr); 4705 /* Step 4: Set cones and supports */ 4706 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4707 /* Step 5: Stratify */ 4708 ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 4709 /* Step 6: Set coordinates for vertices */ 4710 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4711 /* Step 7: Create pointSF */ 4712 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4713 /* Step 8: Create labels */ 4714 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4715 ierr = PetscFree(depthSize);CHKERRQ(ierr); 4716 4717 *dmRefined = rdm; 4718 PetscFunctionReturn(0); 4719 } 4720 4721 #undef __FUNCT__ 4722 #define __FUNCT__ "DMPlexSetRefinementUniform" 4723 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 4724 { 4725 DM_Plex *mesh = (DM_Plex*) dm->data; 4726 4727 PetscFunctionBegin; 4728 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4729 mesh->refinementUniform = refinementUniform; 4730 PetscFunctionReturn(0); 4731 } 4732 4733 #undef __FUNCT__ 4734 #define __FUNCT__ "DMPlexGetRefinementUniform" 4735 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 4736 { 4737 DM_Plex *mesh = (DM_Plex*) dm->data; 4738 4739 PetscFunctionBegin; 4740 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4741 PetscValidPointer(refinementUniform, 2); 4742 *refinementUniform = mesh->refinementUniform; 4743 PetscFunctionReturn(0); 4744 } 4745 4746 #undef __FUNCT__ 4747 #define __FUNCT__ "DMPlexSetRefinementLimit" 4748 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 4749 { 4750 DM_Plex *mesh = (DM_Plex*) dm->data; 4751 4752 PetscFunctionBegin; 4753 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4754 mesh->refinementLimit = refinementLimit; 4755 PetscFunctionReturn(0); 4756 } 4757 4758 #undef __FUNCT__ 4759 #define __FUNCT__ "DMPlexGetRefinementLimit" 4760 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 4761 { 4762 DM_Plex *mesh = (DM_Plex*) dm->data; 4763 4764 PetscFunctionBegin; 4765 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4766 PetscValidPointer(refinementLimit, 2); 4767 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 4768 *refinementLimit = mesh->refinementLimit; 4769 PetscFunctionReturn(0); 4770 } 4771 4772 #undef __FUNCT__ 4773 #define __FUNCT__ "DMPlexGetCellRefiner_Internal" 4774 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 4775 { 4776 PetscInt dim, cStart, cEnd, coneSize, cMax; 4777 PetscErrorCode ierr; 4778 4779 PetscFunctionBegin; 4780 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 4781 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 4782 if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);} 4783 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 4784 ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 4785 switch (dim) { 4786 case 2: 4787 switch (coneSize) { 4788 case 3: 4789 if (cMax >= 0) *cellRefiner = 3; /* Hybrid */ 4790 else *cellRefiner = 1; /* Triangular */ 4791 break; 4792 case 4: 4793 if (cMax >= 0) *cellRefiner = 4; /* Hybrid */ 4794 else *cellRefiner = 2; /* Quadrilateral */ 4795 break; 4796 default: 4797 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 4798 } 4799 break; 4800 case 3: 4801 switch (coneSize) { 4802 case 4: 4803 if (cMax >= 0) *cellRefiner = 7; /* Hybrid */ 4804 else *cellRefiner = 5; /* Tetrahedral */ 4805 break; 4806 case 6: 4807 if (cMax >= 0) *cellRefiner = 8; /* Hybrid */ 4808 else *cellRefiner = 6; /* hexahedral */ 4809 break; 4810 default: 4811 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 4812 } 4813 break; 4814 default: 4815 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 4816 } 4817 PetscFunctionReturn(0); 4818 } 4819