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