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 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) /*ornt[c] < 0 ? (1-(ornt[c]+r))%3 : (ornt[c] + r)%3 */; 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 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 = ornt[c] < 0 ? (-(ornt[c]+1) + 2-r)%3 : (ornt[c] + r)%3; 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 < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, 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) /*ornt[c] < 0 ? (1-(ornt[c]+r))%3 : (ornt[c] + r)%3 */; 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 + (fMax - fStart)*4 + (c - cStart)*8 + 4; 2236 orntNew[1] = 0; 2237 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + 3; 2238 orntNew[2] = ornt[2] < 0 ? -((-(ornt[2]+1)+2)%3+1) : (ornt[2]+2)%3; 2239 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 2240 orntNew[3] = 0; 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 + (cone[3] - fStart)*4 + 3; 2253 orntNew[1] = ornt[3] < 0 ? -((-(ornt[3]+1)+1)%3+1) : (ornt[3]+1)%3; 2254 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 2255 orntNew[2] = 0; 2256 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 2257 orntNew[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 + (fMax - fStart)*4 + (c - cStart)*8 + 7; 2270 orntNew[1] = -2; 2271 coneNew[2] = fStartNew + (cone[0] - fStart)*4 + 3; 2272 orntNew[2] = ornt[0] < 0 ? (-(ornt[0]+1)+1)%3 : -((ornt[0]+1)%3+1); 2273 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 2274 orntNew[3] = -1; 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 + 6; 2287 orntNew[1] = -3; 2288 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 2289 orntNew[2] = -2; 2290 coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3; 2291 orntNew[3] = ornt[2]; 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 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2430 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2431 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2432 for (c = 0; c < coneSize; ++c) { 2433 if (cone[c] == f) break; 2434 } 2435 if (support[s] < cMax) { 2436 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : (ornt[c] < 0 ? faces[c*3+(-(ornt[c]+1)+1+3-r)%3] : faces[c*3+r])); 2437 } else { 2438 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : GetTriSubfaceInverse_Static(ornt[c], r)); 2439 } 2440 } 2441 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 2442 #if 1 2443 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2444 for (p = 0; p < supportSize; ++p) { 2445 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); 2446 } 2447 #endif 2448 } 2449 } 2450 /* Interior cell faces have 3 edges and 2 cells */ 2451 for (c = cStart; c < cMax; ++c) { 2452 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 2453 const PetscInt *cone, *ornt; 2454 PetscInt coneNew[3], orntNew[3]; 2455 PetscInt supportNew[2]; 2456 2457 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2458 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2459 /* Face A: {c, a, d} */ 2460 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+0)%3 : (ornt[0]+2)%3); 2461 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2462 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+0)%3 : (ornt[1]+2)%3); 2463 orntNew[1] = ornt[1] < 0 ? -2 : 0; 2464 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+0)%3 : (ornt[2]+2)%3); 2465 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2466 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2467 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2468 #if 1 2469 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2470 for (p = 0; p < 3; ++p) { 2471 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); 2472 } 2473 #endif 2474 supportNew[0] = (c - cStart)*8 + 0; 2475 supportNew[1] = (c - cStart)*8 + 0+4; 2476 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2477 #if 1 2478 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2479 for (p = 0; p < 2; ++p) { 2480 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); 2481 } 2482 #endif 2483 ++newp; 2484 /* Face B: {a, b, e} */ 2485 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+2)%3 : (ornt[0]+0)%3); 2486 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2487 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+2)%3 : (ornt[3]+0)%3); 2488 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2489 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+1)%3 : (ornt[1]+1)%3); 2490 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2491 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2492 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2493 #if 1 2494 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); 2495 for (p = 0; p < 3; ++p) { 2496 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); 2497 } 2498 #endif 2499 supportNew[0] = (c - cStart)*8 + 1; 2500 supportNew[1] = (c - cStart)*8 + 1+4; 2501 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2502 #if 1 2503 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2504 for (p = 0; p < 2; ++p) { 2505 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); 2506 } 2507 #endif 2508 ++newp; 2509 /* Face C: {c, f, b} */ 2510 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+2)%3 : (ornt[2]+0)%3); 2511 orntNew[0] = ornt[2] < 0 ? -2 : 0; 2512 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+0)%3 : (ornt[3]+2)%3); 2513 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2514 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+1)%3 : (ornt[0]+1)%3); 2515 orntNew[2] = ornt[0] < 0 ? -2 : 0; 2516 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2517 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2518 #if 1 2519 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2520 for (p = 0; p < 3; ++p) { 2521 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); 2522 } 2523 #endif 2524 supportNew[0] = (c - cStart)*8 + 2; 2525 supportNew[1] = (c - cStart)*8 + 2+4; 2526 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2527 #if 1 2528 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2529 for (p = 0; p < 2; ++p) { 2530 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); 2531 } 2532 #endif 2533 ++newp; 2534 /* Face D: {d, e, f} */ 2535 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+2)%3 : (ornt[1]+0)%3); 2536 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2537 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+1)%3 : (ornt[3]+1)%3); 2538 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2539 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+1)%3 : (ornt[2]+1)%3); 2540 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2541 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2542 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2543 #if 1 2544 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2545 for (p = 0; p < 3; ++p) { 2546 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); 2547 } 2548 #endif 2549 supportNew[0] = (c - cStart)*8 + 3; 2550 supportNew[1] = (c - cStart)*8 + 3+4; 2551 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2552 #if 1 2553 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2554 for (p = 0; p < 2; ++p) { 2555 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); 2556 } 2557 #endif 2558 ++newp; 2559 /* Face E: {d, f, a} */ 2560 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+1)%3 : (ornt[2]+1)%3); 2561 orntNew[0] = ornt[2] < 0 ? 0 : -2; 2562 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2563 orntNew[1] = 0; 2564 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+0)%3 : (ornt[1]+2)%3); 2565 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2566 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2567 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2568 #if 1 2569 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2570 for (p = 0; p < 3; ++p) { 2571 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); 2572 } 2573 #endif 2574 supportNew[0] = (c - cStart)*8 + 0+4; 2575 supportNew[1] = (c - cStart)*8 + 3+4; 2576 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2577 #if 1 2578 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2579 for (p = 0; p < 2; ++p) { 2580 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); 2581 } 2582 #endif 2583 ++newp; 2584 /* Face F: {c, a, f} */ 2585 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+0)%3 : (ornt[0]+2)%3); 2586 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2587 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2588 orntNew[1] = -2; 2589 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+2)%3 : (ornt[2]+0)%3); 2590 orntNew[2] = ornt[1] < 0 ? 0 : -2; 2591 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2592 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2593 #if 1 2594 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2595 for (p = 0; p < 3; ++p) { 2596 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); 2597 } 2598 #endif 2599 supportNew[0] = (c - cStart)*8 + 0+4; 2600 supportNew[1] = (c - cStart)*8 + 2+4; 2601 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2602 #if 1 2603 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2604 for (p = 0; p < 2; ++p) { 2605 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); 2606 } 2607 #endif 2608 ++newp; 2609 /* Face G: {e, a, f} */ 2610 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+1)%3 : (ornt[1]+1)%3); 2611 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2612 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2613 orntNew[1] = -2; 2614 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+1)%3 : (ornt[3]+1)%3); 2615 orntNew[2] = ornt[3] < 0 ? 0 : -2; 2616 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2617 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2618 #if 1 2619 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2620 for (p = 0; p < 3; ++p) { 2621 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); 2622 } 2623 #endif 2624 supportNew[0] = (c - cStart)*8 + 1+4; 2625 supportNew[1] = (c - cStart)*8 + 3+4; 2626 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2627 #if 1 2628 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2629 for (p = 0; p < 2; ++p) { 2630 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); 2631 } 2632 #endif 2633 ++newp; 2634 /* Face H: {a, b, f} */ 2635 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+2)%3 : (ornt[0]+0)%3); 2636 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2637 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+0)%3 : (ornt[3]+2)%3); 2638 orntNew[1] = ornt[3] < 0 ? 0 : -2; 2639 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2640 orntNew[2] = 0; 2641 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2642 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2643 #if 1 2644 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2645 for (p = 0; p < 3; ++p) { 2646 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); 2647 } 2648 #endif 2649 supportNew[0] = (c - cStart)*8 + 1+4; 2650 supportNew[1] = (c - cStart)*8 + 2+4; 2651 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2652 #if 1 2653 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2654 for (p = 0; p < 2; ++p) { 2655 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); 2656 } 2657 #endif 2658 ++newp; 2659 } 2660 /* Hybrid split faces have 4 edges and same cells */ 2661 for (f = fMax; f < fEnd; ++f) { 2662 const PetscInt *cone, *ornt, *support; 2663 PetscInt coneNew[4], orntNew[4]; 2664 PetscInt supportNew[2], size, s, c; 2665 2666 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2667 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2668 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2669 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2670 for (r = 0; r < 2; ++r) { 2671 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 2672 2673 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 2674 orntNew[0] = ornt[0]; 2675 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 2676 orntNew[1] = ornt[1]; 2677 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 2678 orntNew[2+r] = 0; 2679 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 2680 orntNew[3-r] = 0; 2681 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2682 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2683 #if 1 2684 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 2685 for (p = 0; p < 2; ++p) { 2686 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 2687 } 2688 for (p = 2; p < 4; ++p) { 2689 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); 2690 } 2691 #endif 2692 for (s = 0; s < size; ++s) { 2693 const PetscInt *coneCell, *orntCell, *fornt; 2694 2695 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 2696 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 2697 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 2698 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 2699 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 2700 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (fornt[c-2] < 0 ? 1-r : r))%3; 2701 } 2702 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2703 #if 1 2704 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 2705 for (p = 0; p < size; ++p) { 2706 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); 2707 } 2708 #endif 2709 } 2710 } 2711 /* Hybrid cell faces have 4 edges and 2 cells */ 2712 for (c = cMax; c < cEnd; ++c) { 2713 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 2714 const PetscInt *cone, *ornt; 2715 PetscInt coneNew[4], orntNew[4]; 2716 PetscInt supportNew[2]; 2717 2718 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2719 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2720 for (r = 0; r < 3; ++r) { 2721 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], (r+2)%3); 2722 orntNew[0] = 0; 2723 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], (r+2)%3); 2724 orntNew[1] = 0; 2725 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+GetTriSubface_Static(ornt[0], (r+2)%3)] - fMax); 2726 orntNew[2] = 0; 2727 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+GetTriSubface_Static(ornt[0], r)] - fMax); 2728 orntNew[3] = 0; 2729 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 2730 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 2731 #if 1 2732 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); 2733 for (p = 0; p < 2; ++p) { 2734 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); 2735 } 2736 for (p = 2; p < 4; ++p) { 2737 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); 2738 } 2739 #endif 2740 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 2741 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 2742 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 2743 #if 1 2744 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); 2745 for (p = 0; p < 2; ++p) { 2746 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); 2747 } 2748 #endif 2749 } 2750 } 2751 /* Interior split edges have 2 vertices and the same faces as the parent */ 2752 for (e = eStart; e < eMax; ++e) { 2753 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 2754 2755 for (r = 0; r < 2; ++r) { 2756 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 2757 const PetscInt *cone, *ornt, *support; 2758 PetscInt coneNew[2], coneSize, c, supportSize, s; 2759 2760 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 2761 coneNew[0] = vStartNew + (cone[0] - vStart); 2762 coneNew[1] = vStartNew + (cone[1] - vStart); 2763 coneNew[(r+1)%2] = newv; 2764 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2765 #if 1 2766 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2767 for (p = 0; p < 2; ++p) { 2768 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); 2769 } 2770 #endif 2771 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 2772 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2773 for (s = 0; s < supportSize; ++s) { 2774 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2775 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2776 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2777 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 2778 if (support[s] < fMax) { 2779 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 2780 } else { 2781 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 2782 } 2783 } 2784 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2785 #if 1 2786 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2787 for (p = 0; p < supportSize; ++p) { 2788 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); 2789 } 2790 #endif 2791 } 2792 } 2793 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 2794 for (f = fStart; f < fMax; ++f) { 2795 const PetscInt *cone, *ornt, *support; 2796 PetscInt coneSize, supportSize, s; 2797 2798 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2799 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2800 for (r = 0; r < 3; ++r) { 2801 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 2802 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 2803 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 2804 -1, -1, 1, 6, 0, 4, 2805 2, 5, 3, 4, -1, -1, 2806 -1, -1, 3, 6, 2, 7}; 2807 2808 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2809 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 2810 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 2811 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2812 #if 1 2813 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2814 for (p = 0; p < 2; ++p) { 2815 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); 2816 } 2817 #endif 2818 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 2819 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 2820 for (s = 0; s < supportSize; ++s) { 2821 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2822 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2823 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2824 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 2825 if (support[s] < cMax) { 2826 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 2827 er = ornt[c] < 0 ? (-(ornt[c]+1) + 2-r)%3 : (ornt[c] + r)%3; 2828 if (er == eint[c]) { 2829 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 2830 } else { 2831 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 2832 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 2833 } 2834 } else { 2835 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (GetTriSubfaceInverse_Static(ornt[c], r) + 1)%3; 2836 } 2837 } 2838 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2839 #if 1 2840 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2841 for (p = 0; p < intFaces; ++p) { 2842 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); 2843 } 2844 #endif 2845 } 2846 } 2847 /* Interior cell edges have 2 vertices and 4 faces */ 2848 for (c = cStart; c < cMax; ++c) { 2849 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2850 const PetscInt *cone, *ornt, *fcone; 2851 PetscInt coneNew[2], supportNew[4], find; 2852 2853 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2854 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2855 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 2856 find = GetTriEdge_Static(ornt[0], 0); 2857 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2858 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 2859 find = GetTriEdge_Static(ornt[2], 1); 2860 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2861 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2862 #if 1 2863 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2864 for (p = 0; p < 2; ++p) { 2865 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); 2866 } 2867 #endif 2868 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 2869 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 2870 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 2871 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 2872 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2873 #if 1 2874 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2875 for (p = 0; p < 4; ++p) { 2876 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); 2877 } 2878 #endif 2879 } 2880 /* Hybrid edges have two vertices and the same faces */ 2881 for (e = eMax; e < eEnd; ++e) { 2882 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 2883 const PetscInt *cone, *support, *fcone; 2884 PetscInt coneNew[2], size, fsize, s; 2885 2886 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 2887 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 2888 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2889 coneNew[0] = vStartNew + (cone[0] - vStart); 2890 coneNew[1] = vStartNew + (cone[1] - vStart); 2891 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2892 #if 1 2893 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 2894 for (p = 0; p < 2; ++p) { 2895 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); 2896 } 2897 #endif 2898 for (s = 0; s < size; ++s) { 2899 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 2900 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 2901 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 2902 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 2903 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 2904 } 2905 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2906 #if 1 2907 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 2908 for (p = 0; p < size; ++p) { 2909 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); 2910 } 2911 #endif 2912 } 2913 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 2914 for (f = fMax; f < fEnd; ++f) { 2915 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 2916 const PetscInt *cone, *support, *ccone, *cornt; 2917 PetscInt coneNew[2], size, csize, s; 2918 2919 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2920 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2921 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2922 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 2923 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 2924 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2925 #if 1 2926 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 2927 for (p = 0; p < 2; ++p) { 2928 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); 2929 } 2930 #endif 2931 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 2932 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 2933 for (s = 0; s < size; ++s) { 2934 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 2935 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 2936 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 2937 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 2938 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]); 2939 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); 2940 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; 2941 } 2942 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2943 #if 1 2944 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 2945 for (p = 0; p < 2+size*2; ++p) { 2946 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); 2947 } 2948 #endif 2949 } 2950 /* Interior vertices have identical supports */ 2951 for (v = vStart; v < vEnd; ++v) { 2952 const PetscInt newp = vStartNew + (v - vStart); 2953 const PetscInt *support, *cone; 2954 PetscInt size, s; 2955 2956 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2957 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2958 for (s = 0; s < size; ++s) { 2959 PetscInt r = 0; 2960 2961 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2962 if (cone[1] == v) r = 1; 2963 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 2964 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 2965 } 2966 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2967 #if 1 2968 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2969 for (p = 0; p < size; ++p) { 2970 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); 2971 } 2972 #endif 2973 } 2974 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 2975 for (e = eStart; e < eMax; ++e) { 2976 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 2977 const PetscInt *cone, *support; 2978 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 2979 2980 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 2981 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2982 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 2983 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 2984 for (s = 0; s < size; ++s) { 2985 PetscInt r = 0; 2986 2987 if (support[s] < fMax) { 2988 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2989 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2990 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 2991 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 2992 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 2993 faceSize += 2; 2994 } else { 2995 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 2996 ++faceSize; 2997 } 2998 } 2999 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3000 for (s = 0; s < starSize*2; s += 2) { 3001 const PetscInt *cone, *ornt; 3002 PetscInt e01, e23; 3003 3004 if ((star[s] >= cStart) && (star[s] < cMax)) { 3005 /* Check edge 0-1 */ 3006 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3007 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3008 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 3009 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 3010 /* Check edge 2-3 */ 3011 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3012 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3013 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 3014 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 3015 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 3016 } 3017 } 3018 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3019 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3020 #if 1 3021 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3022 for (p = 0; p < 2+faceSize+cellSize; ++p) { 3023 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); 3024 } 3025 #endif 3026 } 3027 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3028 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 3029 break; 3030 case 6: 3031 /* Hex 3D */ 3032 /* 3033 Bottom (viewed from top) Top 3034 1---------2---------2 7---------2---------6 3035 | | | | | | 3036 | B 2 C | | H 2 G | 3037 | | | | | | 3038 3----3----0----1----1 3----3----0----1----1 3039 | | | | | | 3040 | A 0 D | | E 0 F | 3041 | | | | | | 3042 0---------0---------3 4---------0---------5 3043 */ 3044 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 3045 for (c = cStart; c < cEnd; ++c) { 3046 const PetscInt newp = (c - cStart)*8; 3047 const PetscInt *cone, *ornt; 3048 PetscInt coneNew[6], orntNew[6]; 3049 3050 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3051 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3052 /* A hex */ 3053 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 3054 orntNew[0] = ornt[0]; 3055 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3056 orntNew[1] = 0; 3057 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 3058 orntNew[2] = ornt[2]; 3059 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3060 orntNew[3] = 0; 3061 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3062 orntNew[4] = 0; 3063 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 3064 orntNew[5] = ornt[5]; 3065 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3066 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3067 #if 1 3068 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); 3069 for (p = 0; p < 6; ++p) { 3070 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); 3071 } 3072 #endif 3073 /* B hex */ 3074 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 3075 orntNew[0] = ornt[0]; 3076 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3077 orntNew[1] = 0; 3078 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3079 orntNew[2] = -1; 3080 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 3081 orntNew[3] = ornt[3]; 3082 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3083 orntNew[4] = 0; 3084 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 3085 orntNew[5] = ornt[5]; 3086 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3087 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3088 #if 1 3089 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); 3090 for (p = 0; p < 6; ++p) { 3091 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); 3092 } 3093 #endif 3094 /* C hex */ 3095 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 3096 orntNew[0] = ornt[0]; 3097 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3098 orntNew[1] = 0; 3099 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3100 orntNew[2] = -1; 3101 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 3102 orntNew[3] = ornt[3]; 3103 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 3104 orntNew[4] = ornt[4]; 3105 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3106 orntNew[5] = -4; 3107 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3108 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3109 #if 1 3110 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); 3111 for (p = 0; p < 6; ++p) { 3112 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); 3113 } 3114 #endif 3115 /* D hex */ 3116 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 3117 orntNew[0] = ornt[0]; 3118 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3119 orntNew[1] = 0; 3120 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 3121 orntNew[2] = ornt[2]; 3122 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3123 orntNew[3] = 0; 3124 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 3125 orntNew[4] = ornt[4]; 3126 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3127 orntNew[5] = -4; 3128 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3129 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3130 #if 1 3131 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); 3132 for (p = 0; p < 6; ++p) { 3133 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); 3134 } 3135 #endif 3136 /* E hex */ 3137 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3138 orntNew[0] = -4; 3139 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 3140 orntNew[1] = ornt[1]; 3141 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 3142 orntNew[2] = ornt[2]; 3143 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3144 orntNew[3] = 0; 3145 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3146 orntNew[4] = -1; 3147 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 3148 orntNew[5] = ornt[5]; 3149 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3150 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3151 #if 1 3152 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); 3153 for (p = 0; p < 6; ++p) { 3154 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); 3155 } 3156 #endif 3157 /* F hex */ 3158 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3159 orntNew[0] = -4; 3160 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 3161 orntNew[1] = ornt[1]; 3162 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 3163 orntNew[2] = ornt[2]; 3164 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3165 orntNew[3] = -1; 3166 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 3167 orntNew[4] = ornt[4]; 3168 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3169 orntNew[5] = 1; 3170 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3171 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3172 #if 1 3173 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); 3174 for (p = 0; p < 6; ++p) { 3175 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); 3176 } 3177 #endif 3178 /* G hex */ 3179 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3180 orntNew[0] = -4; 3181 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 3182 orntNew[1] = ornt[1]; 3183 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3184 orntNew[2] = 0; 3185 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 3186 orntNew[3] = ornt[3]; 3187 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 3188 orntNew[4] = ornt[4]; 3189 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3190 orntNew[5] = -3; 3191 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3192 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3193 #if 1 3194 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); 3195 for (p = 0; p < 6; ++p) { 3196 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); 3197 } 3198 #endif 3199 /* H hex */ 3200 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3201 orntNew[0] = -4; 3202 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 3203 orntNew[1] = ornt[1]; 3204 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3205 orntNew[2] = -1; 3206 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 3207 orntNew[3] = ornt[3]; 3208 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3209 orntNew[4] = 3; 3210 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 3211 orntNew[5] = ornt[5]; 3212 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3213 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3214 #if 1 3215 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); 3216 for (p = 0; p < 6; ++p) { 3217 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); 3218 } 3219 #endif 3220 } 3221 /* Split faces have 4 edges and the same cells as the parent */ 3222 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3223 ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 3224 for (f = fStart; f < fEnd; ++f) { 3225 for (r = 0; r < 4; ++r) { 3226 /* TODO: This can come from GetFaces_Internal() */ 3227 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}; 3228 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 3229 const PetscInt *cone, *ornt, *support; 3230 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 3231 3232 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3233 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3234 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 3235 orntNew[(r+3)%4] = ornt[(r+3)%4]; 3236 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 3237 orntNew[(r+0)%4] = ornt[r]; 3238 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 3239 orntNew[(r+1)%4] = 0; 3240 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 3241 orntNew[(r+2)%4] = -2; 3242 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3243 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3244 #if 1 3245 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3246 for (p = 0; p < 4; ++p) { 3247 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); 3248 } 3249 #endif 3250 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3251 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3252 for (s = 0; s < supportSize; ++s) { 3253 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3254 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3255 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3256 for (c = 0; c < coneSize; ++c) { 3257 if (cone[c] == f) break; 3258 } 3259 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 3260 } 3261 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3262 #if 1 3263 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3264 for (p = 0; p < supportSize; ++p) { 3265 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); 3266 } 3267 #endif 3268 } 3269 } 3270 /* Interior faces have 4 edges and 2 cells */ 3271 for (c = cStart; c < cEnd; ++c) { 3272 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}; 3273 const PetscInt *cone, *ornt; 3274 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 3275 3276 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3277 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3278 /* A-D face */ 3279 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 3280 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 3281 orntNew[0] = 0; 3282 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3283 orntNew[1] = 0; 3284 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3285 orntNew[2] = -2; 3286 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 3287 orntNew[3] = -2; 3288 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3289 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3290 #if 1 3291 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3292 for (p = 0; p < 4; ++p) { 3293 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); 3294 } 3295 #endif 3296 /* C-D face */ 3297 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 3298 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 3299 orntNew[0] = 0; 3300 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3301 orntNew[1] = 0; 3302 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3303 orntNew[2] = -2; 3304 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 3305 orntNew[3] = -2; 3306 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3307 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3308 #if 1 3309 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3310 for (p = 0; p < 4; ++p) { 3311 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); 3312 } 3313 #endif 3314 /* B-C face */ 3315 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 3316 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 3317 orntNew[0] = -2; 3318 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 3319 orntNew[1] = 0; 3320 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3321 orntNew[2] = 0; 3322 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3323 orntNew[3] = -2; 3324 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3325 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3326 #if 1 3327 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3328 for (p = 0; p < 4; ++p) { 3329 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); 3330 } 3331 #endif 3332 /* A-B face */ 3333 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 3334 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 3335 orntNew[0] = -2; 3336 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 3337 orntNew[1] = 0; 3338 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3339 orntNew[2] = 0; 3340 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3341 orntNew[3] = -2; 3342 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3343 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3344 #if 1 3345 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3346 for (p = 0; p < 4; ++p) { 3347 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); 3348 } 3349 #endif 3350 /* E-F face */ 3351 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 3352 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3353 orntNew[0] = -2; 3354 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 3355 orntNew[1] = -2; 3356 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 3357 orntNew[2] = 0; 3358 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3359 orntNew[3] = 0; 3360 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3361 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3362 #if 1 3363 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3364 for (p = 0; p < 4; ++p) { 3365 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); 3366 } 3367 #endif 3368 /* F-G face */ 3369 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 3370 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3371 orntNew[0] = -2; 3372 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 3373 orntNew[1] = -2; 3374 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 3375 orntNew[2] = 0; 3376 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3377 orntNew[3] = 0; 3378 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3379 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3380 #if 1 3381 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3382 for (p = 0; p < 4; ++p) { 3383 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); 3384 } 3385 #endif 3386 /* G-H face */ 3387 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 3388 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 3389 orntNew[0] = -2; 3390 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 3391 orntNew[1] = 0; 3392 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3393 orntNew[2] = 0; 3394 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3395 orntNew[3] = -2; 3396 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3397 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3398 #if 1 3399 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3400 for (p = 0; p < 4; ++p) { 3401 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); 3402 } 3403 #endif 3404 /* E-H face */ 3405 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 3406 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3407 orntNew[0] = -2; 3408 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 3409 orntNew[1] = -2; 3410 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 3411 orntNew[2] = 0; 3412 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3413 orntNew[3] = 0; 3414 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3415 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3416 #if 1 3417 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3418 for (p = 0; p < 4; ++p) { 3419 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); 3420 } 3421 #endif 3422 /* A-E face */ 3423 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 3424 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 3425 orntNew[0] = 0; 3426 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3427 orntNew[1] = 0; 3428 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3429 orntNew[2] = -2; 3430 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 3431 orntNew[3] = -2; 3432 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3433 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3434 #if 1 3435 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3436 for (p = 0; p < 4; ++p) { 3437 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); 3438 } 3439 #endif 3440 /* D-F face */ 3441 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 3442 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 3443 orntNew[0] = -2; 3444 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 3445 orntNew[1] = 0; 3446 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3447 orntNew[2] = 0; 3448 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3449 orntNew[3] = -2; 3450 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3451 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3452 #if 1 3453 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3454 for (p = 0; p < 4; ++p) { 3455 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); 3456 } 3457 #endif 3458 /* C-G face */ 3459 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 3460 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3461 orntNew[0] = -2; 3462 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 3463 orntNew[1] = -2; 3464 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 3465 orntNew[2] = 0; 3466 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3467 orntNew[3] = 0; 3468 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3469 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3470 #if 1 3471 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3472 for (p = 0; p < 4; ++p) { 3473 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); 3474 } 3475 #endif 3476 /* B-H face */ 3477 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 3478 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3479 orntNew[0] = 0; 3480 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3481 orntNew[1] = -2; 3482 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 3483 orntNew[2] = -2; 3484 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 3485 orntNew[3] = 0; 3486 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3487 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3488 #if 1 3489 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3490 for (p = 0; p < 4; ++p) { 3491 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); 3492 } 3493 #endif 3494 for (r = 0; r < 12; ++r) { 3495 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 3496 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 3497 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 3498 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3499 #if 1 3500 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3501 for (p = 0; p < 2; ++p) { 3502 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); 3503 } 3504 #endif 3505 } 3506 } 3507 /* Split edges have 2 vertices and the same faces as the parent */ 3508 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3509 for (e = eStart; e < eEnd; ++e) { 3510 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3511 3512 for (r = 0; r < 2; ++r) { 3513 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3514 const PetscInt *cone, *ornt, *support; 3515 PetscInt coneNew[2], coneSize, c, supportSize, s; 3516 3517 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3518 coneNew[0] = vStartNew + (cone[0] - vStart); 3519 coneNew[1] = vStartNew + (cone[1] - vStart); 3520 coneNew[(r+1)%2] = newv; 3521 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3522 #if 1 3523 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3524 for (p = 0; p < 2; ++p) { 3525 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); 3526 } 3527 #endif 3528 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3529 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3530 for (s = 0; s < supportSize; ++s) { 3531 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3532 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3533 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3534 for (c = 0; c < coneSize; ++c) { 3535 if (cone[c] == e) break; 3536 } 3537 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 3538 } 3539 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3540 #if 1 3541 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3542 for (p = 0; p < supportSize; ++p) { 3543 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); 3544 } 3545 #endif 3546 } 3547 } 3548 /* Face edges have 2 vertices and 2+cells faces */ 3549 for (f = fStart; f < fEnd; ++f) { 3550 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}; 3551 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 3552 const PetscInt *cone, *coneCell, *orntCell, *support; 3553 PetscInt coneNew[2], coneSize, c, supportSize, s; 3554 3555 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3556 for (r = 0; r < 4; ++r) { 3557 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 3558 3559 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 3560 coneNew[1] = newv; 3561 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3562 #if 1 3563 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3564 for (p = 0; p < 2; ++p) { 3565 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); 3566 } 3567 #endif 3568 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3569 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3570 supportRef[0] = fStartNew + (f - fStart)*4 + r; 3571 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 3572 for (s = 0; s < supportSize; ++s) { 3573 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3574 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 3575 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 3576 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 3577 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 3578 } 3579 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3580 #if 1 3581 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3582 for (p = 0; p < 2+supportSize; ++p) { 3583 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); 3584 } 3585 #endif 3586 } 3587 } 3588 /* Cell edges have 2 vertices and 4 faces */ 3589 for (c = cStart; c < cEnd; ++c) { 3590 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}; 3591 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 3592 const PetscInt *cone; 3593 PetscInt coneNew[2], supportNew[4]; 3594 3595 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3596 for (r = 0; r < 6; ++r) { 3597 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 3598 3599 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 3600 coneNew[1] = newv; 3601 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3602 #if 1 3603 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3604 for (p = 0; p < 2; ++p) { 3605 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); 3606 } 3607 #endif 3608 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 3609 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3610 #if 1 3611 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3612 for (p = 0; p < 4; ++p) { 3613 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); 3614 } 3615 #endif 3616 } 3617 } 3618 /* Old vertices have identical supports */ 3619 for (v = vStart; v < vEnd; ++v) { 3620 const PetscInt newp = vStartNew + (v - vStart); 3621 const PetscInt *support, *cone; 3622 PetscInt size, s; 3623 3624 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3625 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3626 for (s = 0; s < size; ++s) { 3627 PetscInt r = 0; 3628 3629 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3630 if (cone[1] == v) r = 1; 3631 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3632 } 3633 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3634 #if 1 3635 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3636 for (p = 0; p < size; ++p) { 3637 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); 3638 } 3639 #endif 3640 } 3641 /* Edge vertices have 2 + faces supports */ 3642 for (e = eStart; e < eEnd; ++e) { 3643 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3644 const PetscInt *cone, *support; 3645 PetscInt size, s; 3646 3647 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3648 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3649 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3650 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3651 for (s = 0; s < size; ++s) { 3652 PetscInt r; 3653 3654 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3655 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 3656 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 3657 } 3658 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3659 #if 1 3660 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3661 for (p = 0; p < 2+size; ++p) { 3662 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); 3663 } 3664 #endif 3665 } 3666 /* Face vertices have 4 + cells supports */ 3667 for (f = fStart; f < fEnd; ++f) { 3668 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 3669 const PetscInt *cone, *support; 3670 PetscInt size, s; 3671 3672 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3673 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3674 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (e - eStart)*2 + (f - fStart)*4 + r; 3675 for (s = 0; s < size; ++s) { 3676 PetscInt r; 3677 3678 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3679 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 3680 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 3681 } 3682 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3683 #if 1 3684 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3685 for (p = 0; p < 4+size; ++p) { 3686 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); 3687 } 3688 #endif 3689 } 3690 /* Cell vertices have 6 supports */ 3691 for (c = cStart; c < cEnd; ++c) { 3692 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 3693 PetscInt supportNew[6]; 3694 3695 for (r = 0; r < 6; ++r) { 3696 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 3697 } 3698 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3699 } 3700 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3701 break; 3702 default: 3703 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 3704 } 3705 PetscFunctionReturn(0); 3706 } 3707 3708 #undef __FUNCT__ 3709 #define __FUNCT__ "CellRefinerSetCoordinates" 3710 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 3711 { 3712 PetscSection coordSection, coordSectionNew; 3713 Vec coordinates, coordinatesNew; 3714 PetscScalar *coords, *coordsNew; 3715 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 3716 PetscInt dim, depth, coordSizeNew, cStart, cEnd, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 3717 PetscErrorCode ierr; 3718 3719 PetscFunctionBegin; 3720 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 3721 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3722 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 3723 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 3724 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 3725 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 3726 ierr = DMPlexGetHybridBounds(dm, NULL, &fMax, &eMax, NULL);CHKERRQ(ierr); 3727 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);} 3728 ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr); 3729 ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 3730 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 3731 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 3732 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dim);CHKERRQ(ierr); 3733 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 3734 if (fMax < 0) fMax = fEnd; 3735 if (eMax < 0) eMax = eEnd; 3736 /* All vertices have the dim coordinates */ 3737 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 3738 ierr = PetscSectionSetDof(coordSectionNew, v, dim);CHKERRQ(ierr); 3739 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dim);CHKERRQ(ierr); 3740 } 3741 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 3742 ierr = DMPlexSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr); 3743 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 3744 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 3745 ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr); 3746 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 3747 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 3748 ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr); 3749 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 3750 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 3751 switch (refiner) { 3752 case 0: break; 3753 case 6: /* Hex 3D */ 3754 /* Face vertices have the average of corner coordinates */ 3755 for (f = fStart; f < fEnd; ++f) { 3756 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 3757 PetscInt *cone = NULL; 3758 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 3759 3760 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3761 for (p = 0; p < closureSize*2; p += 2) { 3762 const PetscInt point = cone[p]; 3763 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 3764 } 3765 for (v = 0; v < coneSize; ++v) { 3766 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 3767 } 3768 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3769 for (d = 0; d < dim; ++d) { 3770 coordsNew[offnew+d] = 0.0; 3771 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 3772 coordsNew[offnew+d] /= coneSize; 3773 } 3774 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3775 } 3776 case 2: /* Hex 2D */ 3777 /* Cell vertices have the average of corner coordinates */ 3778 for (c = cStart; c < cEnd; ++c) { 3779 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (c - cStart) + (dim > 2 ? (fEnd - fStart) : 0); 3780 PetscInt *cone = NULL; 3781 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 3782 3783 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3784 for (p = 0; p < closureSize*2; p += 2) { 3785 const PetscInt point = cone[p]; 3786 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 3787 } 3788 for (v = 0; v < coneSize; ++v) { 3789 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 3790 } 3791 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3792 for (d = 0; d < dim; ++d) { 3793 coordsNew[offnew+d] = 0.0; 3794 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 3795 coordsNew[offnew+d] /= coneSize; 3796 } 3797 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3798 } 3799 case 1: /* Simplicial 2D */ 3800 case 3: /* Hybrid Simplicial 2D */ 3801 case 5: /* Simplicial 3D */ 3802 case 7: /* Hybrid Simplicial 3D */ 3803 /* Edge vertices have the average of endpoint coordinates */ 3804 for (e = eStart; e < eMax; ++e) { 3805 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3806 const PetscInt *cone; 3807 PetscInt coneSize, offA, offB, offnew, d; 3808 3809 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 3810 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 3811 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3812 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 3813 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 3814 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3815 for (d = 0; d < dim; ++d) { 3816 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]); 3817 } 3818 } 3819 /* Old vertices have the same coordinates */ 3820 for (v = vStart; v < vEnd; ++v) { 3821 const PetscInt newv = vStartNew + (v - vStart); 3822 PetscInt off, offnew, d; 3823 3824 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 3825 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3826 for (d = 0; d < dim; ++d) { 3827 coordsNew[offnew+d] = coords[off+d]; 3828 } 3829 } 3830 break; 3831 default: 3832 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 3833 } 3834 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 3835 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 3836 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 3837 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 3838 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 3839 PetscFunctionReturn(0); 3840 } 3841 3842 #undef __FUNCT__ 3843 #define __FUNCT__ "DMPlexCreateProcessSF" 3844 static PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 3845 { 3846 PetscInt numRoots, numLeaves, l; 3847 const PetscInt *localPoints; 3848 const PetscSFNode *remotePoints; 3849 PetscInt *localPointsNew; 3850 PetscSFNode *remotePointsNew; 3851 PetscInt *ranks, *ranksNew; 3852 PetscErrorCode ierr; 3853 3854 PetscFunctionBegin; 3855 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 3856 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 3857 for (l = 0; l < numLeaves; ++l) { 3858 ranks[l] = remotePoints[l].rank; 3859 } 3860 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 3861 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 3862 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 3863 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 3864 for (l = 0; l < numLeaves; ++l) { 3865 ranksNew[l] = ranks[l]; 3866 localPointsNew[l] = l; 3867 remotePointsNew[l].index = 0; 3868 remotePointsNew[l].rank = ranksNew[l]; 3869 } 3870 ierr = PetscFree(ranks);CHKERRQ(ierr); 3871 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr); 3872 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 3873 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 3874 ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 3875 PetscFunctionReturn(0); 3876 } 3877 3878 #undef __FUNCT__ 3879 #define __FUNCT__ "CellRefinerCreateSF" 3880 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 3881 { 3882 PetscSF sf, sfNew, sfProcess; 3883 IS processRanks; 3884 MPI_Datatype depthType; 3885 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 3886 const PetscInt *localPoints, *neighbors; 3887 const PetscSFNode *remotePoints; 3888 PetscInt *localPointsNew; 3889 PetscSFNode *remotePointsNew; 3890 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 3891 PetscInt depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 3892 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 3893 PetscErrorCode ierr; 3894 3895 PetscFunctionBegin; 3896 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 3897 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3898 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 3899 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 3900 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 3901 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 3902 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 3903 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 3904 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 3905 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 3906 /* Caculate size of new SF */ 3907 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 3908 if (numRoots < 0) PetscFunctionReturn(0); 3909 for (l = 0; l < numLeaves; ++l) { 3910 const PetscInt p = localPoints[l]; 3911 3912 switch (refiner) { 3913 case 1: 3914 /* Simplicial 2D */ 3915 if ((p >= vStart) && (p < vEnd)) { 3916 /* Old vertices stay the same */ 3917 ++numLeavesNew; 3918 } else if ((p >= fStart) && (p < fEnd)) { 3919 /* Old faces add new faces and vertex */ 3920 numLeavesNew += 2 + 1; 3921 } else if ((p >= cStart) && (p < cEnd)) { 3922 /* Old cells add new cells and interior faces */ 3923 numLeavesNew += 4 + 3; 3924 } 3925 break; 3926 case 2: 3927 /* Hex 2D */ 3928 if ((p >= vStart) && (p < vEnd)) { 3929 /* Old vertices stay the same */ 3930 ++numLeavesNew; 3931 } else if ((p >= fStart) && (p < fEnd)) { 3932 /* Old faces add new faces and vertex */ 3933 numLeavesNew += 2 + 1; 3934 } else if ((p >= cStart) && (p < cEnd)) { 3935 /* Old cells add new cells, interior faces, and vertex */ 3936 numLeavesNew += 4 + 4 + 1; 3937 } 3938 break; 3939 case 5: 3940 /* Simplicial 3D */ 3941 if ((p >= vStart) && (p < vEnd)) { 3942 /* Old vertices stay the same */ 3943 ++numLeavesNew; 3944 } else if ((p >= eStart) && (p < eEnd)) { 3945 /* Old edges add new edges and vertex */ 3946 numLeavesNew += 2 + 1; 3947 } else if ((p >= fStart) && (p < fEnd)) { 3948 /* Old faces add new faces and face edges */ 3949 numLeavesNew += 4 + 3; 3950 } else if ((p >= cStart) && (p < cEnd)) { 3951 /* Old cells add new cells and interior faces and edges */ 3952 numLeavesNew += 8 + 8 + 1; 3953 } 3954 break; 3955 case 7: 3956 /* Hybrid Simplicial 3D */ 3957 if ((p >= vStart) && (p < vEnd)) { 3958 /* Interior vertices stay the same */ 3959 ++numLeavesNew; 3960 } else if ((p >= eStart) && (p < eMax)) { 3961 /* Interior edges add new edges and vertex */ 3962 numLeavesNew += 2 + 1; 3963 } else if ((p >= eMax) && (p < eEnd)) { 3964 /* Hybrid edges stay the same */ 3965 ++numLeavesNew; 3966 } else if ((p >= fStart) && (p < fMax)) { 3967 /* Interior faces add new faces and edges */ 3968 numLeavesNew += 4 + 3; 3969 } else if ((p >= fMax) && (p < fEnd)) { 3970 /* Hybrid faces add new faces and edges */ 3971 numLeavesNew += 2 + 1; 3972 } else if ((p >= cStart) && (p < cMax)) { 3973 /* Interior cells add new cells, faces, and edges */ 3974 numLeavesNew += 8 + 8 + 1; 3975 } else if ((p >= cMax) && (p < cEnd)) { 3976 /* Hybrid cells add new cells and faces */ 3977 numLeavesNew += 4 + 3; 3978 } 3979 break; 3980 case 6: 3981 /* Hex 3D */ 3982 if ((p >= vStart) && (p < vEnd)) { 3983 /* Old vertices stay the same */ 3984 ++numLeavesNew; 3985 } else if ((p >= eStart) && (p < eEnd)) { 3986 /* Old edges add new edges, and vertex */ 3987 numLeavesNew += 2 + 1; 3988 } else if ((p >= fStart) && (p < fEnd)) { 3989 /* Old faces add new faces, edges, and vertex */ 3990 numLeavesNew += 4 + 4 + 1; 3991 } else if ((p >= cStart) && (p < cEnd)) { 3992 /* Old cells add new cells, faces, edges, and vertex */ 3993 numLeavesNew += 8 + 12 + 6 + 1; 3994 } 3995 break; 3996 default: 3997 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 3998 } 3999 } 4000 /* Communicate depthSizes for each remote rank */ 4001 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 4002 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 4003 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 4004 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 4005 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 4006 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 4007 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 4008 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 4009 for (n = 0; n < numNeighbors; ++n) { 4010 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 4011 } 4012 depthSizeOld[depth] = cMax; 4013 depthSizeOld[0] = vMax; 4014 depthSizeOld[depth-1] = fMax; 4015 depthSizeOld[1] = eMax; 4016 4017 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 4018 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 4019 4020 depthSizeOld[depth] = cEnd - cStart; 4021 depthSizeOld[0] = vEnd - vStart; 4022 depthSizeOld[depth-1] = fEnd - fStart; 4023 depthSizeOld[1] = eEnd - eStart; 4024 4025 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 4026 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 4027 for (n = 0; n < numNeighbors; ++n) { 4028 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 4029 } 4030 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 4031 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 4032 /* Calculate new point SF */ 4033 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 4034 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 4035 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 4036 for (l = 0, m = 0; l < numLeaves; ++l) { 4037 PetscInt p = localPoints[l]; 4038 PetscInt rp = remotePoints[l].index, n; 4039 PetscMPIInt rrank = remotePoints[l].rank; 4040 4041 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 4042 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 4043 switch (refiner) { 4044 case 1: 4045 /* Simplicial 2D */ 4046 if ((p >= vStart) && (p < vEnd)) { 4047 /* Old vertices stay the same */ 4048 localPointsNew[m] = vStartNew + (p - vStart); 4049 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4050 remotePointsNew[m].rank = rrank; 4051 ++m; 4052 } else if ((p >= fStart) && (p < fEnd)) { 4053 /* Old faces add new faces and vertex */ 4054 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 4055 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 4056 remotePointsNew[m].rank = rrank; 4057 ++m; 4058 for (r = 0; r < 2; ++r, ++m) { 4059 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 4060 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 4061 remotePointsNew[m].rank = rrank; 4062 } 4063 } else if ((p >= cStart) && (p < cEnd)) { 4064 /* Old cells add new cells and interior faces */ 4065 for (r = 0; r < 4; ++r, ++m) { 4066 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4067 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4068 remotePointsNew[m].rank = rrank; 4069 } 4070 for (r = 0; r < 3; ++r, ++m) { 4071 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 4072 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 4073 remotePointsNew[m].rank = rrank; 4074 } 4075 } 4076 break; 4077 case 2: 4078 /* Hex 2D */ 4079 if ((p >= vStart) && (p < vEnd)) { 4080 /* Old vertices stay the same */ 4081 localPointsNew[m] = vStartNew + (p - vStart); 4082 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4083 remotePointsNew[m].rank = rrank; 4084 ++m; 4085 } else if ((p >= fStart) && (p < fEnd)) { 4086 /* Old faces add new faces and vertex */ 4087 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 4088 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 4089 remotePointsNew[m].rank = rrank; 4090 ++m; 4091 for (r = 0; r < 2; ++r, ++m) { 4092 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 4093 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 4094 remotePointsNew[m].rank = rrank; 4095 } 4096 } else if ((p >= cStart) && (p < cEnd)) { 4097 /* Old cells add new cells, interior faces, and vertex */ 4098 for (r = 0; r < 4; ++r, ++m) { 4099 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4100 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4101 remotePointsNew[m].rank = rrank; 4102 } 4103 for (r = 0; r < 4; ++r, ++m) { 4104 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 4105 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r; 4106 remotePointsNew[m].rank = rrank; 4107 } 4108 for (r = 0; r < 1; ++r, ++m) { 4109 localPointsNew[m] = vStartNew + (fEnd - fStart) + (p - cStart) + r; 4110 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 4111 remotePointsNew[m].rank = rrank; 4112 } 4113 } 4114 break; 4115 case 3: 4116 /* Hybrid simplicial 2D */ 4117 if ((p >= vStart) && (p < vEnd)) { 4118 /* Old vertices stay the same */ 4119 localPointsNew[m] = vStartNew + (p - vStart); 4120 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4121 remotePointsNew[m].rank = rrank; 4122 ++m; 4123 } else if ((p >= fStart) && (p < fMax)) { 4124 /* Old interior faces add new faces and vertex */ 4125 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 4126 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 4127 remotePointsNew[m].rank = rrank; 4128 ++m; 4129 for (r = 0; r < 2; ++r, ++m) { 4130 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 4131 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 4132 remotePointsNew[m].rank = rrank; 4133 } 4134 } else if ((p >= fMax) && (p < fEnd)) { 4135 /* Old hybrid faces stay the same */ 4136 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 4137 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 4138 remotePointsNew[m].rank = rrank; 4139 ++m; 4140 } else if ((p >= cStart) && (p < cMax)) { 4141 /* Old interior cells add new cells and interior faces */ 4142 for (r = 0; r < 4; ++r, ++m) { 4143 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4144 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4145 remotePointsNew[m].rank = rrank; 4146 } 4147 for (r = 0; r < 3; ++r, ++m) { 4148 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 4149 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 4150 remotePointsNew[m].rank = rrank; 4151 } 4152 } else if ((p >= cStart) && (p < cMax)) { 4153 /* Old hybrid cells add new cells and hybrid face */ 4154 for (r = 0; r < 2; ++r, ++m) { 4155 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4156 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4157 remotePointsNew[m].rank = rrank; 4158 } 4159 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 4160 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]); 4161 remotePointsNew[m].rank = rrank; 4162 ++m; 4163 } 4164 break; 4165 case 5: 4166 /* Simplicial 3D */ 4167 if ((p >= vStart) && (p < vEnd)) { 4168 /* Old vertices stay the same */ 4169 localPointsNew[m] = vStartNew + (p - vStart); 4170 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4171 remotePointsNew[m].rank = rrank; 4172 ++m; 4173 } else if ((p >= eStart) && (p < eEnd)) { 4174 /* Old edges add new edges and vertex */ 4175 for (r = 0; r < 2; ++r, ++m) { 4176 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 4177 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 4178 remotePointsNew[m].rank = rrank; 4179 } 4180 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 4181 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 4182 remotePointsNew[m].rank = rrank; 4183 ++m; 4184 } else if ((p >= fStart) && (p < fEnd)) { 4185 /* Old faces add new faces and face edges */ 4186 for (r = 0; r < 4; ++r, ++m) { 4187 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 4188 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 4189 remotePointsNew[m].rank = rrank; 4190 } 4191 for (r = 0; r < 3; ++r, ++m) { 4192 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 4193 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*3 + r; 4194 remotePointsNew[m].rank = rrank; 4195 } 4196 } else if ((p >= cStart) && (p < cEnd)) { 4197 /* Old cells add new cells and interior faces and edges */ 4198 for (r = 0; r < 8; ++r, ++m) { 4199 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 4200 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 4201 remotePointsNew[m].rank = rrank; 4202 } 4203 for (r = 0; r < 8; ++r, ++m) { 4204 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 4205 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*8 + r; 4206 remotePointsNew[m].rank = rrank; 4207 } 4208 for (r = 0; r < 1; ++r, ++m) { 4209 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 4210 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*1 + r; 4211 remotePointsNew[m].rank = rrank; 4212 } 4213 } 4214 break; 4215 case 7: 4216 /* Hybrid Simplicial 3D */ 4217 if ((p >= vStart) && (p < vEnd)) { 4218 /* Interior vertices stay the same */ 4219 localPointsNew[m] = vStartNew + (p - vStart); 4220 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4221 remotePointsNew[m].rank = rrank; 4222 ++m; 4223 } else if ((p >= eStart) && (p < eMax)) { 4224 /* Interior edges add new edges and vertex */ 4225 for (r = 0; r < 2; ++r, ++m) { 4226 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 4227 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 4228 remotePointsNew[m].rank = rrank; 4229 } 4230 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 4231 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 4232 remotePointsNew[m].rank = rrank; 4233 ++m; 4234 } else if ((p >= eMax) && (p < eEnd)) { 4235 /* Hybrid edges stay the same */ 4236 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 4237 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]); 4238 remotePointsNew[m].rank = rrank; 4239 ++m; 4240 } else if ((p >= fStart) && (p < fMax)) { 4241 /* Interior faces add new faces and edges */ 4242 for (r = 0; r < 4; ++r, ++m) { 4243 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 4244 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 4245 remotePointsNew[m].rank = rrank; 4246 } 4247 for (r = 0; r < 3; ++r, ++m) { 4248 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 4249 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 4250 remotePointsNew[m].rank = rrank; 4251 } 4252 } else if ((p >= fMax) && (p < fEnd)) { 4253 /* Hybrid faces add new faces and edges */ 4254 for (r = 0; r < 2; ++r, ++m) { 4255 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fStart)*2 + r; 4256 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; 4257 remotePointsNew[m].rank = rrank; 4258 } 4259 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart) + (cMax - cStart) + (fEnd - fMax); 4260 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]); 4261 remotePointsNew[m].rank = rrank; 4262 ++m; 4263 } else if ((p >= cStart) && (p < cMax)) { 4264 /* Interior cells add new cells, faces, and edges */ 4265 for (r = 0; r < 8; ++r, ++m) { 4266 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 4267 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 4268 remotePointsNew[m].rank = rrank; 4269 } 4270 for (r = 0; r < 8; ++r, ++m) { 4271 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 4272 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 4273 remotePointsNew[m].rank = rrank; 4274 } 4275 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + r; 4276 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; 4277 remotePointsNew[m].rank = rrank; 4278 ++m; 4279 } else if ((p >= cMax) && (p < cEnd)) { 4280 /* Hybrid cells add new cells and faces */ 4281 for (r = 0; r < 4; ++r, ++m) { 4282 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 4283 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 4284 remotePointsNew[m].rank = rrank; 4285 } 4286 for (r = 0; r < 3; ++r, ++m) { 4287 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*4 + (p - cMax)*3 + r; 4288 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; 4289 remotePointsNew[m].rank = rrank; 4290 } 4291 } 4292 break; 4293 case 6: 4294 /* Hex 3D */ 4295 if ((p >= vStart) && (p < vEnd)) { 4296 /* Old vertices stay the same */ 4297 localPointsNew[m] = vStartNew + (p - vStart); 4298 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4299 remotePointsNew[m].rank = rrank; 4300 ++m; 4301 } else if ((p >= eStart) && (p < eEnd)) { 4302 /* Old edges add new edges and vertex */ 4303 for (r = 0; r < 2; ++r, ++m) { 4304 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 4305 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 4306 remotePointsNew[m].rank = rrank; 4307 } 4308 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 4309 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 4310 remotePointsNew[m].rank = rrank; 4311 ++m; 4312 } else if ((p >= fStart) && (p < fEnd)) { 4313 /* Old faces add new faces, edges, and vertex */ 4314 for (r = 0; r < 4; ++r, ++m) { 4315 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 4316 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 4317 remotePointsNew[m].rank = rrank; 4318 } 4319 for (r = 0; r < 4; ++r, ++m) { 4320 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 4321 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*4 + r; 4322 remotePointsNew[m].rank = rrank; 4323 } 4324 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 4325 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]); 4326 remotePointsNew[m].rank = rrank; 4327 ++m; 4328 } else if ((p >= cStart) && (p < cEnd)) { 4329 /* Old cells add new cells, faces, edges, and vertex */ 4330 for (r = 0; r < 8; ++r, ++m) { 4331 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 4332 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 4333 remotePointsNew[m].rank = rrank; 4334 } 4335 for (r = 0; r < 12; ++r, ++m) { 4336 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 4337 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*12 + r; 4338 remotePointsNew[m].rank = rrank; 4339 } 4340 for (r = 0; r < 6; ++r, ++m) { 4341 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 4342 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*6 + r; 4343 remotePointsNew[m].rank = rrank; 4344 } 4345 for (r = 0; r < 1; ++r, ++m) { 4346 localPointsNew[m] = vStartNew + (eEnd - eStart) + (fEnd - fStart) + (p - cStart) + r; 4347 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 4348 remotePointsNew[m].rank = rrank; 4349 } 4350 } 4351 break; 4352 default: 4353 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 4354 } 4355 } 4356 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew); 4357 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 4358 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 4359 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 4360 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 4361 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 4362 PetscFunctionReturn(0); 4363 } 4364 4365 #undef __FUNCT__ 4366 #define __FUNCT__ "CellRefinerCreateLabels" 4367 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 4368 { 4369 PetscInt numLabels, l; 4370 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 4371 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 4372 PetscErrorCode ierr; 4373 4374 PetscFunctionBegin; 4375 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 4376 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 4377 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 4378 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 4379 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 4380 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 4381 ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 4382 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 4383 switch (refiner) { 4384 case 0: break; 4385 case 7: 4386 case 8: 4387 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 4388 case 3: 4389 case 4: 4390 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 4391 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 4392 } 4393 for (l = 0; l < numLabels; ++l) { 4394 DMLabel label, labelNew; 4395 const char *lname; 4396 PetscBool isDepth; 4397 IS valueIS; 4398 const PetscInt *values; 4399 PetscInt numValues, val; 4400 4401 ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr); 4402 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 4403 if (isDepth) continue; 4404 ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr); 4405 ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr); 4406 ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 4407 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 4408 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 4409 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 4410 for (val = 0; val < numValues; ++val) { 4411 IS pointIS; 4412 const PetscInt *points; 4413 PetscInt numPoints, n; 4414 4415 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 4416 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 4417 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 4418 for (n = 0; n < numPoints; ++n) { 4419 const PetscInt p = points[n]; 4420 switch (refiner) { 4421 case 1: 4422 /* Simplicial 2D */ 4423 if ((p >= vStart) && (p < vEnd)) { 4424 /* Old vertices stay the same */ 4425 newp = vStartNew + (p - vStart); 4426 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4427 } else if ((p >= fStart) && (p < fEnd)) { 4428 /* Old faces add new faces and vertex */ 4429 newp = vStartNew + (vEnd - vStart) + (p - fStart); 4430 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4431 for (r = 0; r < 2; ++r) { 4432 newp = fStartNew + (p - fStart)*2 + r; 4433 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4434 } 4435 } else if ((p >= cStart) && (p < cEnd)) { 4436 /* Old cells add new cells and interior faces */ 4437 for (r = 0; r < 4; ++r) { 4438 newp = cStartNew + (p - cStart)*4 + r; 4439 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4440 } 4441 for (r = 0; r < 3; ++r) { 4442 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 4443 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4444 } 4445 } 4446 break; 4447 case 2: 4448 /* Hex 2D */ 4449 if ((p >= vStart) && (p < vEnd)) { 4450 /* Old vertices stay the same */ 4451 newp = vStartNew + (p - vStart); 4452 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4453 } else if ((p >= fStart) && (p < fEnd)) { 4454 /* Old faces add new faces and vertex */ 4455 newp = vStartNew + (vEnd - vStart) + (p - fStart); 4456 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4457 for (r = 0; r < 2; ++r) { 4458 newp = fStartNew + (p - fStart)*2 + r; 4459 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4460 } 4461 } else if ((p >= cStart) && (p < cEnd)) { 4462 /* Old cells add new cells and interior faces and vertex */ 4463 for (r = 0; r < 4; ++r) { 4464 newp = cStartNew + (p - cStart)*4 + r; 4465 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4466 } 4467 for (r = 0; r < 4; ++r) { 4468 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 4469 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4470 } 4471 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 4472 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4473 } 4474 break; 4475 case 3: 4476 /* Hybrid simplicial 2D */ 4477 if ((p >= vStart) && (p < vEnd)) { 4478 /* Old vertices stay the same */ 4479 newp = vStartNew + (p - vStart); 4480 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4481 } else if ((p >= fStart) && (p < fMax)) { 4482 /* Old interior faces add new faces and vertex */ 4483 newp = vStartNew + (vEnd - vStart) + (p - fStart); 4484 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4485 for (r = 0; r < 2; ++r) { 4486 newp = fStartNew + (p - fStart)*2 + r; 4487 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4488 } 4489 } else if ((p >= fMax) && (p < fEnd)) { 4490 /* Old hybrid faces stay the same */ 4491 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 4492 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4493 } else if ((p >= cStart) && (p < cMax)) { 4494 /* Old interior cells add new cells and interior faces */ 4495 for (r = 0; r < 4; ++r) { 4496 newp = cStartNew + (p - cStart)*4 + r; 4497 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4498 } 4499 for (r = 0; r < 3; ++r) { 4500 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 4501 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4502 } 4503 } else if ((p >= cMax) && (p < cEnd)) { 4504 /* Old hybrid cells add new cells and hybrid face */ 4505 for (r = 0; r < 2; ++r) { 4506 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 4507 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4508 } 4509 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 4510 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4511 } 4512 break; 4513 case 5: 4514 /* Simplicial 3D */ 4515 if ((p >= vStart) && (p < vEnd)) { 4516 /* Old vertices stay the same */ 4517 newp = vStartNew + (p - vStart); 4518 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4519 } else if ((p >= eStart) && (p < eEnd)) { 4520 /* Old edges add new edges and vertex */ 4521 for (r = 0; r < 2; ++r) { 4522 newp = eStartNew + (p - eStart)*2 + r; 4523 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4524 } 4525 newp = vStartNew + (vEnd - vStart) + (p - eStart); 4526 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4527 } else if ((p >= fStart) && (p < fEnd)) { 4528 /* Old faces add new faces and edges */ 4529 for (r = 0; r < 4; ++r) { 4530 newp = fStartNew + (p - fStart)*4 + r; 4531 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4532 } 4533 for (r = 0; r < 3; ++r) { 4534 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 4535 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4536 } 4537 } else if ((p >= cStart) && (p < cEnd)) { 4538 /* Old cells add new cells and interior faces and edges */ 4539 for (r = 0; r < 8; ++r) { 4540 newp = cStartNew + (p - cStart)*8 + r; 4541 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4542 } 4543 for (r = 0; r < 8; ++r) { 4544 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 4545 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4546 } 4547 for (r = 0; r < 1; ++r) { 4548 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 4549 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4550 } 4551 } 4552 break; 4553 case 7: 4554 /* Hybrid Simplicial 3D */ 4555 if ((p >= vStart) && (p < vEnd)) { 4556 /* Interior vertices stay the same */ 4557 newp = vStartNew + (p - vStart); 4558 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4559 } else if ((p >= eStart) && (p < eMax)) { 4560 /* Interior edges add new edges and vertex */ 4561 for (r = 0; r < 2; ++r) { 4562 newp = eStartNew + (p - eStart)*2 + r; 4563 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4564 } 4565 newp = vStartNew + (vEnd - vStart) + (p - eStart); 4566 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4567 } else if ((p >= eMax) && (p < eEnd)) { 4568 /* Hybrid edges stay the same */ 4569 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 4570 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4571 } else if ((p >= fStart) && (p < fMax)) { 4572 /* Interior faces add new faces and edges */ 4573 for (r = 0; r < 4; ++r) { 4574 newp = fStartNew + (p - fStart)*4 + r; 4575 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4576 } 4577 for (r = 0; r < 3; ++r) { 4578 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 4579 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4580 } 4581 } else if ((p >= fMax) && (p < fEnd)) { 4582 /* Hybrid faces add new faces and edges */ 4583 for (r = 0; r < 2; ++r) { 4584 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 4585 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4586 } 4587 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 4588 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4589 } else if ((p >= cStart) && (p < cMax)) { 4590 /* Interior cells add new cells, faces, and edges */ 4591 for (r = 0; r < 8; ++r) { 4592 newp = cStartNew + (p - cStart)*8 + r; 4593 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4594 } 4595 for (r = 0; r < 8; ++r) { 4596 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 4597 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4598 } 4599 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 4600 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4601 } else if ((p >= cMax) && (p < cEnd)) { 4602 /* Hybrid cells add new cells and faces */ 4603 for (r = 0; r < 4; ++r) { 4604 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 4605 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4606 } 4607 for (r = 0; r < 3; ++r) { 4608 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 4609 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4610 } 4611 } 4612 break; 4613 case 6: 4614 /* Hex 3D */ 4615 if ((p >= vStart) && (p < vEnd)) { 4616 /* Old vertices stay the same */ 4617 newp = vStartNew + (p - vStart); 4618 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4619 } else if ((p >= eStart) && (p < eEnd)) { 4620 /* Old edges add new edges and vertex */ 4621 for (r = 0; r < 2; ++r) { 4622 newp = eStartNew + (p - eStart)*2 + r; 4623 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4624 } 4625 newp = vStartNew + (vEnd - vStart) + (p - eStart); 4626 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4627 } else if ((p >= fStart) && (p < fEnd)) { 4628 /* Old faces add new faces, edges, and vertex */ 4629 for (r = 0; r < 4; ++r) { 4630 newp = fStartNew + (p - fStart)*4 + r; 4631 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4632 } 4633 for (r = 0; r < 4; ++r) { 4634 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 4635 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4636 } 4637 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 4638 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4639 } else if ((p >= cStart) && (p < cEnd)) { 4640 /* Old cells add new cells, faces, edges, and vertex */ 4641 for (r = 0; r < 8; ++r) { 4642 newp = cStartNew + (p - cStart)*8 + r; 4643 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4644 } 4645 for (r = 0; r < 12; ++r) { 4646 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 4647 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4648 } 4649 for (r = 0; r < 6; ++r) { 4650 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 4651 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4652 } 4653 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 4654 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4655 } 4656 break; 4657 default: 4658 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 4659 } 4660 } 4661 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 4662 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 4663 } 4664 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 4665 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 4666 if (0) { 4667 ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr); 4668 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 4669 ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 4670 } 4671 } 4672 PetscFunctionReturn(0); 4673 } 4674 4675 #undef __FUNCT__ 4676 #define __FUNCT__ "DMPlexRefineUniform_Internal" 4677 /* This will only work for interpolated meshes */ 4678 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 4679 { 4680 DM rdm; 4681 PetscInt *depthSize; 4682 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 4683 PetscErrorCode ierr; 4684 4685 PetscFunctionBegin; 4686 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 4687 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 4688 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 4689 ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr); 4690 /* Calculate number of new points of each depth */ 4691 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 4692 ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr); 4693 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 4694 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 4695 /* Step 1: Set chart */ 4696 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 4697 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 4698 /* Step 2: Set cone/support sizes */ 4699 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4700 /* Step 3: Setup refined DM */ 4701 ierr = DMSetUp(rdm);CHKERRQ(ierr); 4702 /* Step 4: Set cones and supports */ 4703 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4704 /* Step 5: Stratify */ 4705 ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 4706 /* Step 6: Set coordinates for vertices */ 4707 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4708 /* Step 7: Create pointSF */ 4709 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4710 /* Step 8: Create labels */ 4711 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4712 ierr = PetscFree(depthSize);CHKERRQ(ierr); 4713 4714 *dmRefined = rdm; 4715 PetscFunctionReturn(0); 4716 } 4717 4718 #undef __FUNCT__ 4719 #define __FUNCT__ "DMPlexSetRefinementUniform" 4720 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 4721 { 4722 DM_Plex *mesh = (DM_Plex*) dm->data; 4723 4724 PetscFunctionBegin; 4725 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4726 mesh->refinementUniform = refinementUniform; 4727 PetscFunctionReturn(0); 4728 } 4729 4730 #undef __FUNCT__ 4731 #define __FUNCT__ "DMPlexGetRefinementUniform" 4732 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 4733 { 4734 DM_Plex *mesh = (DM_Plex*) dm->data; 4735 4736 PetscFunctionBegin; 4737 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4738 PetscValidPointer(refinementUniform, 2); 4739 *refinementUniform = mesh->refinementUniform; 4740 PetscFunctionReturn(0); 4741 } 4742 4743 #undef __FUNCT__ 4744 #define __FUNCT__ "DMPlexSetRefinementLimit" 4745 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 4746 { 4747 DM_Plex *mesh = (DM_Plex*) dm->data; 4748 4749 PetscFunctionBegin; 4750 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4751 mesh->refinementLimit = refinementLimit; 4752 PetscFunctionReturn(0); 4753 } 4754 4755 #undef __FUNCT__ 4756 #define __FUNCT__ "DMPlexGetRefinementLimit" 4757 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 4758 { 4759 DM_Plex *mesh = (DM_Plex*) dm->data; 4760 4761 PetscFunctionBegin; 4762 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4763 PetscValidPointer(refinementLimit, 2); 4764 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 4765 *refinementLimit = mesh->refinementLimit; 4766 PetscFunctionReturn(0); 4767 } 4768 4769 #undef __FUNCT__ 4770 #define __FUNCT__ "DMPlexGetCellRefiner_Internal" 4771 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 4772 { 4773 PetscInt dim, cStart, cEnd, coneSize, cMax; 4774 PetscErrorCode ierr; 4775 4776 PetscFunctionBegin; 4777 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 4778 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 4779 if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);} 4780 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 4781 ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 4782 switch (dim) { 4783 case 2: 4784 switch (coneSize) { 4785 case 3: 4786 if (cMax >= 0) *cellRefiner = 3; /* Hybrid */ 4787 else *cellRefiner = 1; /* Triangular */ 4788 break; 4789 case 4: 4790 if (cMax >= 0) *cellRefiner = 4; /* Hybrid */ 4791 else *cellRefiner = 2; /* Quadrilateral */ 4792 break; 4793 default: 4794 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 4795 } 4796 break; 4797 case 3: 4798 switch (coneSize) { 4799 case 4: 4800 if (cMax >= 0) *cellRefiner = 7; /* Hybrid */ 4801 else *cellRefiner = 5; /* Tetrahedral */ 4802 break; 4803 case 6: 4804 if (cMax >= 0) *cellRefiner = 8; /* Hybrid */ 4805 else *cellRefiner = 6; /* hexahedral */ 4806 break; 4807 default: 4808 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 4809 } 4810 break; 4811 default: 4812 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 4813 } 4814 PetscFunctionReturn(0); 4815 } 4816