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 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1719 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1720 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1721 for (c = 0; c < coneSize; ++c) { 1722 if (cone[c] == f) break; 1723 } 1724 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])); 1725 } 1726 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 1727 #if 1 1728 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1729 for (p = 0; p < supportSize; ++p) { 1730 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); 1731 } 1732 #endif 1733 } 1734 } 1735 /* Interior faces have 3 edges and 2 cells */ 1736 for (c = cStart; c < cEnd; ++c) { 1737 PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 1738 const PetscInt *cone, *ornt; 1739 PetscInt coneNew[3], orntNew[3]; 1740 PetscInt supportNew[2]; 1741 1742 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1743 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1744 /* Face A: {c, a, d} */ 1745 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+0)%3 : (ornt[0]+2)%3); 1746 orntNew[0] = ornt[0] < 0 ? -2 : 0; 1747 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+0)%3 : (ornt[1]+2)%3); 1748 orntNew[1] = ornt[1] < 0 ? -2 : 0; 1749 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+0)%3 : (ornt[2]+2)%3); 1750 orntNew[2] = ornt[2] < 0 ? -2 : 0; 1751 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1752 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1753 #if 1 1754 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1755 for (p = 0; p < 3; ++p) { 1756 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); 1757 } 1758 #endif 1759 supportNew[0] = (c - cStart)*8 + 0; 1760 supportNew[1] = (c - cStart)*8 + 0+4; 1761 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1762 #if 1 1763 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1764 for (p = 0; p < 2; ++p) { 1765 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); 1766 } 1767 #endif 1768 ++newp; 1769 /* Face B: {a, b, e} */ 1770 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+2)%3 : (ornt[0]+0)%3); 1771 orntNew[0] = ornt[0] < 0 ? -2 : 0; 1772 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+2)%3 : (ornt[3]+0)%3); 1773 orntNew[1] = ornt[3] < 0 ? -2 : 0; 1774 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+1)%3 : (ornt[1]+1)%3); 1775 orntNew[2] = ornt[1] < 0 ? -2 : 0; 1776 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1777 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1778 #if 1 1779 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); 1780 for (p = 0; p < 3; ++p) { 1781 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); 1782 } 1783 #endif 1784 supportNew[0] = (c - cStart)*8 + 1; 1785 supportNew[1] = (c - cStart)*8 + 1+4; 1786 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1787 #if 1 1788 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1789 for (p = 0; p < 2; ++p) { 1790 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); 1791 } 1792 #endif 1793 ++newp; 1794 /* Face C: {c, f, b} */ 1795 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+2)%3 : (ornt[2]+0)%3); 1796 orntNew[0] = ornt[2] < 0 ? -2 : 0; 1797 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+0)%3 : (ornt[3]+2)%3); 1798 orntNew[1] = ornt[3] < 0 ? -2 : 0; 1799 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+1)%3 : (ornt[0]+1)%3); 1800 orntNew[2] = ornt[0] < 0 ? -2 : 0; 1801 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1802 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1803 #if 1 1804 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1805 for (p = 0; p < 3; ++p) { 1806 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); 1807 } 1808 #endif 1809 supportNew[0] = (c - cStart)*8 + 2; 1810 supportNew[1] = (c - cStart)*8 + 2+4; 1811 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1812 #if 1 1813 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1814 for (p = 0; p < 2; ++p) { 1815 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); 1816 } 1817 #endif 1818 ++newp; 1819 /* Face D: {d, e, f} */ 1820 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+2)%3 : (ornt[1]+0)%3); 1821 orntNew[0] = ornt[1] < 0 ? -2 : 0; 1822 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+1)%3 : (ornt[3]+1)%3); 1823 orntNew[1] = ornt[3] < 0 ? -2 : 0; 1824 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+1)%3 : (ornt[2]+1)%3); 1825 orntNew[2] = ornt[2] < 0 ? -2 : 0; 1826 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1827 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1828 #if 1 1829 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1830 for (p = 0; p < 3; ++p) { 1831 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); 1832 } 1833 #endif 1834 supportNew[0] = (c - cStart)*8 + 3; 1835 supportNew[1] = (c - cStart)*8 + 3+4; 1836 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1837 #if 1 1838 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1839 for (p = 0; p < 2; ++p) { 1840 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); 1841 } 1842 #endif 1843 ++newp; 1844 /* Face E: {d, f, a} */ 1845 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+1)%3 : (ornt[2]+1)%3); 1846 orntNew[0] = ornt[2] < 0 ? 0 : -2; 1847 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 1848 orntNew[1] = 0; 1849 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+0)%3 : (ornt[1]+2)%3); 1850 orntNew[2] = ornt[1] < 0 ? -2 : 0; 1851 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1852 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1853 #if 1 1854 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1855 for (p = 0; p < 3; ++p) { 1856 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); 1857 } 1858 #endif 1859 supportNew[0] = (c - cStart)*8 + 0+4; 1860 supportNew[1] = (c - cStart)*8 + 3+4; 1861 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1862 #if 1 1863 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1864 for (p = 0; p < 2; ++p) { 1865 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); 1866 } 1867 #endif 1868 ++newp; 1869 /* Face F: {c, a, f} */ 1870 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+0)%3 : (ornt[0]+2)%3); 1871 orntNew[0] = ornt[0] < 0 ? -2 : 0; 1872 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 1873 orntNew[1] = -2; 1874 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+2)%3 : (ornt[2]+0)%3); 1875 orntNew[2] = ornt[1] < 0 ? 0 : -2; 1876 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1877 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1878 #if 1 1879 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1880 for (p = 0; p < 3; ++p) { 1881 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); 1882 } 1883 #endif 1884 supportNew[0] = (c - cStart)*8 + 0+4; 1885 supportNew[1] = (c - cStart)*8 + 2+4; 1886 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1887 #if 1 1888 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1889 for (p = 0; p < 2; ++p) { 1890 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); 1891 } 1892 #endif 1893 ++newp; 1894 /* Face G: {e, a, f} */ 1895 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+1)%3 : (ornt[1]+1)%3); 1896 orntNew[0] = ornt[1] < 0 ? -2 : 0; 1897 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 1898 orntNew[1] = 0; 1899 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+1)%3 : (ornt[3]+1)%3); 1900 orntNew[2] = ornt[3] < 0 ? 0 : -2; 1901 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1902 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1903 #if 1 1904 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1905 for (p = 0; p < 3; ++p) { 1906 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); 1907 } 1908 #endif 1909 supportNew[0] = (c - cStart)*8 + 1+4; 1910 supportNew[1] = (c - cStart)*8 + 3+4; 1911 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1912 #if 1 1913 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1914 for (p = 0; p < 2; ++p) { 1915 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); 1916 } 1917 #endif 1918 ++newp; 1919 /* Face H: {a, b, f} */ 1920 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+2)%3 : (ornt[0]+0)%3); 1921 orntNew[0] = ornt[0] < 0 ? -2 : 0; 1922 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+0)%3 : (ornt[3]+2)%3); 1923 orntNew[1] = ornt[3] < 0 ? 0 : -2; 1924 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 1925 orntNew[2] = 0; 1926 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1927 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1928 #if 1 1929 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1930 for (p = 0; p < 3; ++p) { 1931 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); 1932 } 1933 #endif 1934 supportNew[0] = (c - cStart)*8 + 1+4; 1935 supportNew[1] = (c - cStart)*8 + 2+4; 1936 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1937 #if 1 1938 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1939 for (p = 0; p < 2; ++p) { 1940 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); 1941 } 1942 #endif 1943 ++newp; 1944 } 1945 /* Split Edges have 2 vertices and the same faces as the parent */ 1946 for (e = eStart; e < eEnd; ++e) { 1947 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 1948 1949 for (r = 0; r < 2; ++r) { 1950 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1951 const PetscInt *cone, *ornt, *support; 1952 PetscInt coneNew[2], coneSize, c, supportSize, s; 1953 1954 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 1955 coneNew[0] = vStartNew + (cone[0] - vStart); 1956 coneNew[1] = vStartNew + (cone[1] - vStart); 1957 coneNew[(r+1)%2] = newv; 1958 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1959 #if 1 1960 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 1961 for (p = 0; p < 2; ++p) { 1962 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); 1963 } 1964 #endif 1965 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 1966 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 1967 for (s = 0; s < supportSize; ++s) { 1968 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1969 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1970 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1971 for (c = 0; c < coneSize; ++c) { 1972 if (cone[c] == e) break; 1973 } 1974 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 1975 } 1976 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1977 #if 1 1978 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 1979 for (p = 0; p < supportSize; ++p) { 1980 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); 1981 } 1982 #endif 1983 } 1984 } 1985 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 1986 for (f = fStart; f < fEnd; ++f) { 1987 const PetscInt *cone, *ornt, *support; 1988 PetscInt coneSize, supportSize, s; 1989 1990 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1991 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1992 for (r = 0; r < 3; ++r) { 1993 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 1994 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 1995 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 1996 -1, -1, 1, 6, 0, 4, 1997 2, 5, 3, 4, -1, -1, 1998 -1, -1, 3, 6, 2, 7}; 1999 2000 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2001 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 2002 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 2003 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2004 #if 1 2005 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2006 for (p = 0; p < 2; ++p) { 2007 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); 2008 } 2009 #endif 2010 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 2011 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 2012 for (s = 0; s < supportSize; ++s) { 2013 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2014 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2015 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2016 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 2017 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 2018 er = ornt[c] < 0 ? (-(ornt[c]+1) + 2-r)%3 : (ornt[c] + r)%3; 2019 if (er == eint[c]) { 2020 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 2021 } else { 2022 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 2023 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 2024 } 2025 } 2026 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2027 #if 1 2028 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2029 for (p = 0; p < intFaces; ++p) { 2030 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); 2031 } 2032 #endif 2033 } 2034 } 2035 /* Interior edges have 2 vertices and 4 faces */ 2036 for (c = cStart; c < cEnd; ++c) { 2037 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2038 const PetscInt *cone, *ornt, *fcone; 2039 PetscInt coneNew[2], supportNew[4], find; 2040 2041 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2042 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2043 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 2044 find = GetTriEdge_Static(ornt[0], 0); 2045 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2046 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 2047 find = GetTriEdge_Static(ornt[2], 1); 2048 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2049 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2050 #if 1 2051 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2052 for (p = 0; p < 2; ++p) { 2053 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); 2054 } 2055 #endif 2056 supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2057 supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2058 supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2059 supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2060 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2061 #if 1 2062 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2063 for (p = 0; p < 4; ++p) { 2064 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); 2065 } 2066 #endif 2067 } 2068 /* Old vertices have identical supports */ 2069 for (v = vStart; v < vEnd; ++v) { 2070 const PetscInt newp = vStartNew + (v - vStart); 2071 const PetscInt *support, *cone; 2072 PetscInt size, s; 2073 2074 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2075 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2076 for (s = 0; s < size; ++s) { 2077 PetscInt r = 0; 2078 2079 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2080 if (cone[1] == v) r = 1; 2081 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 2082 } 2083 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2084 #if 1 2085 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2086 for (p = 0; p < size; ++p) { 2087 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); 2088 } 2089 #endif 2090 } 2091 /* Edge vertices have 2 + face*2 + 0/1 supports */ 2092 for (e = eStart; e < eEnd; ++e) { 2093 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 2094 const PetscInt *cone, *support; 2095 PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 2096 2097 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 2098 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2099 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 2100 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 2101 for (s = 0; s < size; ++s) { 2102 PetscInt r = 0; 2103 2104 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2105 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2106 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 2107 supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 2108 supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 2109 } 2110 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2111 for (s = 0; s < starSize*2; s += 2) { 2112 const PetscInt *cone, *ornt; 2113 PetscInt e01, e23; 2114 2115 if ((star[s] >= cStart) && (star[s] < cEnd)) { 2116 /* Check edge 0-1 */ 2117 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2118 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2119 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 2120 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 2121 /* Check edge 2-3 */ 2122 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2123 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2124 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 2125 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 2126 if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 2127 } 2128 } 2129 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2130 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2131 #if 1 2132 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2133 for (p = 0; p < 2+size*2+cellSize; ++p) { 2134 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); 2135 } 2136 #endif 2137 } 2138 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2139 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 2140 break; 2141 case 7: 2142 /* Hybrid Simplicial 3D */ 2143 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 2144 /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 2145 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 2146 for (c = cStart; c < cMax; ++c) { 2147 const PetscInt newp = cStartNew + (c - cStart)*8; 2148 const PetscInt *cone, *ornt; 2149 PetscInt coneNew[4], orntNew[4]; 2150 2151 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2152 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2153 /* A tetrahedron: {0, a, c, d} */ 2154 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 2155 orntNew[0] = ornt[0]; 2156 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 2157 orntNew[1] = ornt[1]; 2158 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 2159 orntNew[2] = ornt[2]; 2160 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 2161 orntNew[3] = 0; 2162 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2163 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2164 #if 1 2165 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); 2166 for (p = 0; p < 4; ++p) { 2167 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); 2168 } 2169 #endif 2170 /* B tetrahedron: {a, 1, b, e} */ 2171 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 2172 orntNew[0] = ornt[0]; 2173 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 2174 orntNew[1] = ornt[1]; 2175 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 2176 orntNew[2] = 0; 2177 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 2178 orntNew[3] = ornt[3]; 2179 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2180 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2181 #if 1 2182 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); 2183 for (p = 0; p < 4; ++p) { 2184 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); 2185 } 2186 #endif 2187 /* C tetrahedron: {c, b, 2, f} */ 2188 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 2189 orntNew[0] = ornt[0]; 2190 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 2191 orntNew[1] = 0; 2192 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 2193 orntNew[2] = ornt[2]; 2194 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 2195 orntNew[3] = ornt[3]; 2196 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2197 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2198 #if 1 2199 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); 2200 for (p = 0; p < 4; ++p) { 2201 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); 2202 } 2203 #endif 2204 /* D tetrahedron: {d, e, f, 3} */ 2205 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 2206 orntNew[0] = 0; 2207 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 2208 orntNew[1] = ornt[1]; 2209 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 2210 orntNew[2] = ornt[2]; 2211 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 2212 orntNew[3] = ornt[3]; 2213 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2214 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2215 #if 1 2216 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); 2217 for (p = 0; p < 4; ++p) { 2218 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); 2219 } 2220 #endif 2221 /* A' tetrahedron: {d, a, c, f} */ 2222 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 2223 orntNew[0] = -3; 2224 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 2225 orntNew[1] = 0; 2226 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + 3; 2227 orntNew[2] = ornt[2] < 0 ? -((-(ornt[2]+1)+2)%3+1) : (ornt[2]+2)%3; 2228 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 2229 orntNew[3] = 0; 2230 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 2231 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 2232 #if 1 2233 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); 2234 for (p = 0; p < 4; ++p) { 2235 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); 2236 } 2237 #endif 2238 /* B' tetrahedron: {e, b, a, f} */ 2239 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 2240 orntNew[0] = -3; 2241 coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3; 2242 orntNew[1] = ornt[3] < 0 ? -((-(ornt[3]+1)+1)%3+1) : (ornt[3]+1)%3; 2243 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 2244 orntNew[2] = 0; 2245 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 2246 orntNew[3] = 0; 2247 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 2248 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 2249 #if 1 2250 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); 2251 for (p = 0; p < 4; ++p) { 2252 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); 2253 } 2254 #endif 2255 /* C' tetrahedron: {b, f, c, a} */ 2256 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 2257 orntNew[0] = -3; 2258 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 2259 orntNew[1] = -2; 2260 coneNew[2] = fStartNew + (cone[0] - fStart)*4 + 3; 2261 orntNew[2] = ornt[0] < 0 ? (-(ornt[0]+1)+1)%3 : -((ornt[0]+1)%3+1); 2262 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 2263 orntNew[3] = -1; 2264 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 2265 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 2266 #if 1 2267 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); 2268 for (p = 0; p < 4; ++p) { 2269 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); 2270 } 2271 #endif 2272 /* D' tetrahedron: {f, e, d, a} */ 2273 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 2274 orntNew[0] = -3; 2275 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 2276 orntNew[1] = -3; 2277 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 2278 orntNew[2] = -2; 2279 coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3; 2280 orntNew[3] = ornt[2]; 2281 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 2282 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 2283 #if 1 2284 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); 2285 for (p = 0; p < 4; ++p) { 2286 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); 2287 } 2288 #endif 2289 } 2290 /* Hybrid cells have 5 faces */ 2291 for (c = cMax; c < cEnd; ++c) { 2292 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4; 2293 const PetscInt *cone, *ornt, *fornt; 2294 PetscInt coneNew[5], orntNew[5]; 2295 2296 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2297 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2298 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 2299 for (r = 0; r < 3; ++r) { 2300 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 2301 orntNew[0] = ornt[0]; 2302 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 2303 orntNew[1] = ornt[1]; 2304 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); 2305 orntNew[2] = 0; 2306 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); 2307 orntNew[3] = 0; 2308 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 2309 orntNew[4] = 0; 2310 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 2311 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 2312 #if 1 2313 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); 2314 for (p = 0; p < 2; ++p) { 2315 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); 2316 } 2317 for (p = 2; p < 5; ++p) { 2318 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); 2319 } 2320 #endif 2321 } 2322 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 2323 orntNew[0] = 0; 2324 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 2325 orntNew[1] = 0; 2326 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 2327 orntNew[2] = 0; 2328 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 2329 orntNew[3] = 0; 2330 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 2331 orntNew[4] = 0; 2332 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2333 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2334 #if 1 2335 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); 2336 for (p = 0; p < 2; ++p) { 2337 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); 2338 } 2339 for (p = 2; p < 5; ++p) { 2340 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); 2341 } 2342 #endif 2343 } 2344 /* Split faces have 3 edges and the same cells as the parent */ 2345 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2346 ierr = PetscMalloc((2 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr); 2347 for (f = fStart; f < fMax; ++f) { 2348 const PetscInt newp = fStartNew + (f - fStart)*4; 2349 const PetscInt *cone, *ornt, *support; 2350 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 2351 2352 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2353 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2354 /* A triangle */ 2355 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 2356 orntNew[0] = ornt[0]; 2357 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 2358 orntNew[1] = -2; 2359 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 2360 orntNew[2] = ornt[2]; 2361 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2362 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2363 #if 1 2364 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); 2365 for (p = 0; p < 3; ++p) { 2366 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); 2367 } 2368 #endif 2369 /* B triangle */ 2370 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 2371 orntNew[0] = ornt[0]; 2372 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 2373 orntNew[1] = ornt[1]; 2374 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 2375 orntNew[2] = -2; 2376 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2377 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2378 #if 1 2379 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); 2380 for (p = 0; p < 3; ++p) { 2381 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); 2382 } 2383 #endif 2384 /* C triangle */ 2385 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 2386 orntNew[0] = -2; 2387 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 2388 orntNew[1] = ornt[1]; 2389 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 2390 orntNew[2] = ornt[2]; 2391 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2392 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2393 #if 1 2394 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); 2395 for (p = 0; p < 3; ++p) { 2396 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); 2397 } 2398 #endif 2399 /* D triangle */ 2400 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 2401 orntNew[0] = 0; 2402 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 2403 orntNew[1] = 0; 2404 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 2405 orntNew[2] = 0; 2406 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2407 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2408 #if 1 2409 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); 2410 for (p = 0; p < 3; ++p) { 2411 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); 2412 } 2413 #endif 2414 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2415 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2416 for (r = 0; r < 4; ++r) { 2417 for (s = 0; s < supportSize; ++s) { 2418 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2419 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2420 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2421 for (c = 0; c < coneSize; ++c) { 2422 if (cone[c] == f) break; 2423 } 2424 if (support[s] < cMax) { 2425 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])); 2426 } else { 2427 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : GetTriSubfaceInverse_Static(ornt[c], r)); 2428 } 2429 } 2430 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 2431 #if 1 2432 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2433 for (p = 0; p < supportSize; ++p) { 2434 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); 2435 } 2436 #endif 2437 } 2438 } 2439 /* Interior cell faces have 3 edges and 2 cells */ 2440 for (c = cStart; c < cMax; ++c) { 2441 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 2442 const PetscInt *cone, *ornt; 2443 PetscInt coneNew[3], orntNew[3]; 2444 PetscInt supportNew[2]; 2445 2446 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2447 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2448 /* Face A: {c, a, d} */ 2449 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+0)%3 : (ornt[0]+2)%3); 2450 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2451 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+0)%3 : (ornt[1]+2)%3); 2452 orntNew[1] = ornt[1] < 0 ? -2 : 0; 2453 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+0)%3 : (ornt[2]+2)%3); 2454 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2455 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2456 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2457 #if 1 2458 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2459 for (p = 0; p < 3; ++p) { 2460 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); 2461 } 2462 #endif 2463 supportNew[0] = (c - cStart)*8 + 0; 2464 supportNew[1] = (c - cStart)*8 + 0+4; 2465 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2466 #if 1 2467 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2468 for (p = 0; p < 2; ++p) { 2469 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); 2470 } 2471 #endif 2472 ++newp; 2473 /* Face B: {a, b, e} */ 2474 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+2)%3 : (ornt[0]+0)%3); 2475 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2476 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+2)%3 : (ornt[3]+0)%3); 2477 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2478 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+1)%3 : (ornt[1]+1)%3); 2479 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2480 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2481 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2482 #if 1 2483 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); 2484 for (p = 0; p < 3; ++p) { 2485 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); 2486 } 2487 #endif 2488 supportNew[0] = (c - cStart)*8 + 1; 2489 supportNew[1] = (c - cStart)*8 + 1+4; 2490 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2491 #if 1 2492 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2493 for (p = 0; p < 2; ++p) { 2494 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); 2495 } 2496 #endif 2497 ++newp; 2498 /* Face C: {c, f, b} */ 2499 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+2)%3 : (ornt[2]+0)%3); 2500 orntNew[0] = ornt[2] < 0 ? -2 : 0; 2501 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+0)%3 : (ornt[3]+2)%3); 2502 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2503 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+1)%3 : (ornt[0]+1)%3); 2504 orntNew[2] = ornt[0] < 0 ? -2 : 0; 2505 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2506 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2507 #if 1 2508 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2509 for (p = 0; p < 3; ++p) { 2510 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); 2511 } 2512 #endif 2513 supportNew[0] = (c - cStart)*8 + 2; 2514 supportNew[1] = (c - cStart)*8 + 2+4; 2515 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2516 #if 1 2517 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2518 for (p = 0; p < 2; ++p) { 2519 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); 2520 } 2521 #endif 2522 ++newp; 2523 /* Face D: {d, e, f} */ 2524 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+2)%3 : (ornt[1]+0)%3); 2525 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2526 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+1)%3 : (ornt[3]+1)%3); 2527 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2528 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+1)%3 : (ornt[2]+1)%3); 2529 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2530 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2531 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2532 #if 1 2533 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2534 for (p = 0; p < 3; ++p) { 2535 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); 2536 } 2537 #endif 2538 supportNew[0] = (c - cStart)*8 + 3; 2539 supportNew[1] = (c - cStart)*8 + 3+4; 2540 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2541 #if 1 2542 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2543 for (p = 0; p < 2; ++p) { 2544 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); 2545 } 2546 #endif 2547 ++newp; 2548 /* Face E: {d, f, a} */ 2549 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+1)%3 : (ornt[2]+1)%3); 2550 orntNew[0] = ornt[2] < 0 ? 0 : -2; 2551 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2552 orntNew[1] = 0; 2553 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+0)%3 : (ornt[1]+2)%3); 2554 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2555 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2556 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2557 #if 1 2558 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2559 for (p = 0; p < 3; ++p) { 2560 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); 2561 } 2562 #endif 2563 supportNew[0] = (c - cStart)*8 + 0+4; 2564 supportNew[1] = (c - cStart)*8 + 3+4; 2565 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2566 #if 1 2567 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2568 for (p = 0; p < 2; ++p) { 2569 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); 2570 } 2571 #endif 2572 ++newp; 2573 /* Face F: {c, a, f} */ 2574 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+0)%3 : (ornt[0]+2)%3); 2575 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2576 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2577 orntNew[1] = -2; 2578 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+2)%3 : (ornt[2]+0)%3); 2579 orntNew[2] = ornt[1] < 0 ? 0 : -2; 2580 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2581 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2582 #if 1 2583 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2584 for (p = 0; p < 3; ++p) { 2585 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); 2586 } 2587 #endif 2588 supportNew[0] = (c - cStart)*8 + 0+4; 2589 supportNew[1] = (c - cStart)*8 + 2+4; 2590 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2591 #if 1 2592 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2593 for (p = 0; p < 2; ++p) { 2594 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); 2595 } 2596 #endif 2597 ++newp; 2598 /* Face G: {e, a, f} */ 2599 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+1)%3 : (ornt[1]+1)%3); 2600 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2601 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2602 orntNew[1] = -2; 2603 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+1)%3 : (ornt[3]+1)%3); 2604 orntNew[2] = ornt[3] < 0 ? 0 : -2; 2605 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2606 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2607 #if 1 2608 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2609 for (p = 0; p < 3; ++p) { 2610 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); 2611 } 2612 #endif 2613 supportNew[0] = (c - cStart)*8 + 1+4; 2614 supportNew[1] = (c - cStart)*8 + 3+4; 2615 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2616 #if 1 2617 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2618 for (p = 0; p < 2; ++p) { 2619 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); 2620 } 2621 #endif 2622 ++newp; 2623 /* Face H: {a, b, f} */ 2624 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+2)%3 : (ornt[0]+0)%3); 2625 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2626 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+0)%3 : (ornt[3]+2)%3); 2627 orntNew[1] = ornt[3] < 0 ? 0 : -2; 2628 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2629 orntNew[2] = 0; 2630 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2631 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2632 #if 1 2633 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2634 for (p = 0; p < 3; ++p) { 2635 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); 2636 } 2637 #endif 2638 supportNew[0] = (c - cStart)*8 + 1+4; 2639 supportNew[1] = (c - cStart)*8 + 2+4; 2640 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2641 #if 1 2642 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2643 for (p = 0; p < 2; ++p) { 2644 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); 2645 } 2646 #endif 2647 ++newp; 2648 } 2649 /* Hybrid split faces have 4 edges and same cells */ 2650 for (f = fMax; f < fEnd; ++f) { 2651 const PetscInt *cone, *ornt, *support; 2652 PetscInt coneNew[4], orntNew[4]; 2653 PetscInt supportNew[2], size, s, c; 2654 2655 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2656 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2657 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2658 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2659 for (r = 0; r < 2; ++r) { 2660 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 2661 2662 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 2663 orntNew[0] = ornt[0]; 2664 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 2665 orntNew[1] = ornt[1]; 2666 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 2667 orntNew[2+r] = 0; 2668 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 2669 orntNew[3-r] = 0; 2670 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2671 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2672 #if 1 2673 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 2674 for (p = 0; p < 2; ++p) { 2675 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); 2676 } 2677 for (p = 2; p < 4; ++p) { 2678 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); 2679 } 2680 #endif 2681 for (s = 0; s < size; ++s) { 2682 const PetscInt *coneCell, *orntCell, *fornt; 2683 2684 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 2685 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 2686 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 2687 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 2688 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 2689 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (fornt[c-2] < 0 ? 1-r : r))%3; 2690 } 2691 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2692 #if 1 2693 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 2694 for (p = 0; p < size; ++p) { 2695 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); 2696 } 2697 #endif 2698 } 2699 } 2700 /* Hybrid cell faces have 4 edges and 2 cells */ 2701 for (c = cMax; c < cEnd; ++c) { 2702 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 2703 const PetscInt *cone, *ornt; 2704 PetscInt coneNew[4], orntNew[4]; 2705 PetscInt supportNew[2]; 2706 2707 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2708 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2709 for (r = 0; r < 3; ++r) { 2710 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], (r+2)%3); 2711 orntNew[0] = 0; 2712 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], (r+2)%3); 2713 orntNew[1] = 0; 2714 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+GetTriSubface_Static(ornt[0], (r+2)%3)] - fMax); 2715 orntNew[2] = 0; 2716 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+GetTriSubface_Static(ornt[0], r)] - fMax); 2717 orntNew[3] = 0; 2718 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 2719 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 2720 #if 1 2721 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); 2722 for (p = 0; p < 2; ++p) { 2723 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); 2724 } 2725 for (p = 2; p < 4; ++p) { 2726 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); 2727 } 2728 #endif 2729 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 2730 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 2731 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 2732 #if 1 2733 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); 2734 for (p = 0; p < 2; ++p) { 2735 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); 2736 } 2737 #endif 2738 } 2739 } 2740 /* Interior split edges have 2 vertices and the same faces as the parent */ 2741 for (e = eStart; e < eMax; ++e) { 2742 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 2743 2744 for (r = 0; r < 2; ++r) { 2745 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 2746 const PetscInt *cone, *ornt, *support; 2747 PetscInt coneNew[2], coneSize, c, supportSize, s; 2748 2749 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 2750 coneNew[0] = vStartNew + (cone[0] - vStart); 2751 coneNew[1] = vStartNew + (cone[1] - vStart); 2752 coneNew[(r+1)%2] = newv; 2753 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2754 #if 1 2755 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2756 for (p = 0; p < 2; ++p) { 2757 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); 2758 } 2759 #endif 2760 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 2761 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2762 for (s = 0; s < supportSize; ++s) { 2763 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2764 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2765 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2766 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 2767 if (support[s] < fMax) { 2768 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 2769 } else { 2770 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 2771 } 2772 } 2773 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2774 #if 1 2775 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2776 for (p = 0; p < supportSize; ++p) { 2777 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); 2778 } 2779 #endif 2780 } 2781 } 2782 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 2783 for (f = fStart; f < fMax; ++f) { 2784 const PetscInt *cone, *ornt, *support; 2785 PetscInt coneSize, supportSize, s; 2786 2787 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2788 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2789 for (r = 0; r < 3; ++r) { 2790 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 2791 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 2792 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 2793 -1, -1, 1, 6, 0, 4, 2794 2, 5, 3, 4, -1, -1, 2795 -1, -1, 3, 6, 2, 7}; 2796 2797 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2798 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 2799 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 2800 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2801 #if 1 2802 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2803 for (p = 0; p < 2; ++p) { 2804 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); 2805 } 2806 #endif 2807 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 2808 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 2809 for (s = 0; s < supportSize; ++s) { 2810 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2811 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2812 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2813 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 2814 if (support[s] < cMax) { 2815 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 2816 er = ornt[c] < 0 ? (-(ornt[c]+1) + 2-r)%3 : (ornt[c] + r)%3; 2817 if (er == eint[c]) { 2818 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 2819 } else { 2820 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 2821 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 2822 } 2823 } else { 2824 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (GetTriSubfaceInverse_Static(ornt[c], r) + 1)%3; 2825 } 2826 } 2827 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2828 #if 1 2829 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2830 for (p = 0; p < intFaces; ++p) { 2831 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); 2832 } 2833 #endif 2834 } 2835 } 2836 /* Interior cell edges have 2 vertices and 4 faces */ 2837 for (c = cStart; c < cMax; ++c) { 2838 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2839 const PetscInt *cone, *ornt, *fcone; 2840 PetscInt coneNew[2], supportNew[4], find; 2841 2842 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2843 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2844 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 2845 find = GetTriEdge_Static(ornt[0], 0); 2846 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2847 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 2848 find = GetTriEdge_Static(ornt[2], 1); 2849 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2850 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2851 #if 1 2852 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2853 for (p = 0; p < 2; ++p) { 2854 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); 2855 } 2856 #endif 2857 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 2858 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 2859 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 2860 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 2861 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2862 #if 1 2863 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2864 for (p = 0; p < 4; ++p) { 2865 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); 2866 } 2867 #endif 2868 } 2869 /* Hybrid edges have two vertices and the same faces */ 2870 for (e = eMax; e < eEnd; ++e) { 2871 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 2872 const PetscInt *cone, *support, *fcone; 2873 PetscInt coneNew[2], size, fsize, s; 2874 2875 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 2876 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 2877 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2878 coneNew[0] = vStartNew + (cone[0] - vStart); 2879 coneNew[1] = vStartNew + (cone[1] - vStart); 2880 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2881 #if 1 2882 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 2883 for (p = 0; p < 2; ++p) { 2884 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); 2885 } 2886 #endif 2887 for (s = 0; s < size; ++s) { 2888 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 2889 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 2890 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 2891 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 2892 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 2893 } 2894 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2895 #if 1 2896 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 2897 for (p = 0; p < size; ++p) { 2898 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); 2899 } 2900 #endif 2901 } 2902 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 2903 for (f = fMax; f < fEnd; ++f) { 2904 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 2905 const PetscInt *cone, *support, *ccone, *cornt; 2906 PetscInt coneNew[2], size, csize, s; 2907 2908 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2909 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2910 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2911 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 2912 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 2913 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2914 #if 1 2915 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 2916 for (p = 0; p < 2; ++p) { 2917 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); 2918 } 2919 #endif 2920 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 2921 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 2922 for (s = 0; s < size; ++s) { 2923 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 2924 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 2925 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 2926 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 2927 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]); 2928 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); 2929 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; 2930 } 2931 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2932 #if 1 2933 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 2934 for (p = 0; p < 2+size*2; ++p) { 2935 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); 2936 } 2937 #endif 2938 } 2939 /* Interior vertices have identical supports */ 2940 for (v = vStart; v < vEnd; ++v) { 2941 const PetscInt newp = vStartNew + (v - vStart); 2942 const PetscInt *support, *cone; 2943 PetscInt size, s; 2944 2945 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2946 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2947 for (s = 0; s < size; ++s) { 2948 PetscInt r = 0; 2949 2950 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2951 if (cone[1] == v) r = 1; 2952 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 2953 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 2954 } 2955 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2956 #if 1 2957 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2958 for (p = 0; p < size; ++p) { 2959 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); 2960 } 2961 #endif 2962 } 2963 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 2964 for (e = eStart; e < eMax; ++e) { 2965 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 2966 const PetscInt *cone, *support; 2967 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 2968 2969 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 2970 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2971 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 2972 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 2973 for (s = 0; s < size; ++s) { 2974 PetscInt r = 0; 2975 2976 if (support[s] < fMax) { 2977 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2978 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2979 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 2980 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 2981 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 2982 faceSize += 2; 2983 } else { 2984 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 2985 ++faceSize; 2986 } 2987 } 2988 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2989 for (s = 0; s < starSize*2; s += 2) { 2990 const PetscInt *cone, *ornt; 2991 PetscInt e01, e23; 2992 2993 if ((star[s] >= cStart) && (star[s] < cMax)) { 2994 /* Check edge 0-1 */ 2995 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2996 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2997 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 2998 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 2999 /* Check edge 2-3 */ 3000 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3001 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3002 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 3003 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 3004 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 3005 } 3006 } 3007 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3008 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3009 #if 1 3010 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3011 for (p = 0; p < 2+faceSize+cellSize; ++p) { 3012 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); 3013 } 3014 #endif 3015 } 3016 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3017 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 3018 break; 3019 case 6: 3020 /* Hex 3D */ 3021 /* 3022 Bottom (viewed from top) Top 3023 1---------2---------2 7---------2---------6 3024 | | | | | | 3025 | B 2 C | | H 2 G | 3026 | | | | | | 3027 3----3----0----1----1 3----3----0----1----1 3028 | | | | | | 3029 | A 0 D | | E 0 F | 3030 | | | | | | 3031 0---------0---------3 4---------0---------5 3032 */ 3033 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 3034 for (c = cStart; c < cEnd; ++c) { 3035 const PetscInt newp = (c - cStart)*8; 3036 const PetscInt *cone, *ornt; 3037 PetscInt coneNew[6], orntNew[6]; 3038 3039 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3040 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3041 /* A hex */ 3042 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 3043 orntNew[0] = ornt[0]; 3044 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3045 orntNew[1] = 0; 3046 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 3047 orntNew[2] = ornt[2]; 3048 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3049 orntNew[3] = 0; 3050 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3051 orntNew[4] = 0; 3052 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 3053 orntNew[5] = ornt[5]; 3054 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3055 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3056 #if 1 3057 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); 3058 for (p = 0; p < 6; ++p) { 3059 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); 3060 } 3061 #endif 3062 /* B hex */ 3063 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 3064 orntNew[0] = ornt[0]; 3065 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3066 orntNew[1] = 0; 3067 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3068 orntNew[2] = -1; 3069 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 3070 orntNew[3] = ornt[3]; 3071 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3072 orntNew[4] = 0; 3073 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 3074 orntNew[5] = ornt[5]; 3075 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3076 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3077 #if 1 3078 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); 3079 for (p = 0; p < 6; ++p) { 3080 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); 3081 } 3082 #endif 3083 /* C hex */ 3084 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 3085 orntNew[0] = ornt[0]; 3086 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3087 orntNew[1] = 0; 3088 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3089 orntNew[2] = -1; 3090 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 3091 orntNew[3] = ornt[3]; 3092 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 3093 orntNew[4] = ornt[4]; 3094 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3095 orntNew[5] = -4; 3096 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3097 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3098 #if 1 3099 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); 3100 for (p = 0; p < 6; ++p) { 3101 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); 3102 } 3103 #endif 3104 /* D hex */ 3105 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 3106 orntNew[0] = ornt[0]; 3107 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3108 orntNew[1] = 0; 3109 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 3110 orntNew[2] = ornt[2]; 3111 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3112 orntNew[3] = 0; 3113 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 3114 orntNew[4] = ornt[4]; 3115 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3116 orntNew[5] = -4; 3117 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3118 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3119 #if 1 3120 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); 3121 for (p = 0; p < 6; ++p) { 3122 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); 3123 } 3124 #endif 3125 /* E hex */ 3126 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3127 orntNew[0] = -4; 3128 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 3129 orntNew[1] = ornt[1]; 3130 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 3131 orntNew[2] = ornt[2]; 3132 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3133 orntNew[3] = 0; 3134 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3135 orntNew[4] = -1; 3136 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 3137 orntNew[5] = ornt[5]; 3138 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3139 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3140 #if 1 3141 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); 3142 for (p = 0; p < 6; ++p) { 3143 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); 3144 } 3145 #endif 3146 /* F hex */ 3147 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3148 orntNew[0] = -4; 3149 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 3150 orntNew[1] = ornt[1]; 3151 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 3152 orntNew[2] = ornt[2]; 3153 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3154 orntNew[3] = -1; 3155 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 3156 orntNew[4] = ornt[4]; 3157 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3158 orntNew[5] = 1; 3159 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3160 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3161 #if 1 3162 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); 3163 for (p = 0; p < 6; ++p) { 3164 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); 3165 } 3166 #endif 3167 /* G hex */ 3168 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3169 orntNew[0] = -4; 3170 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 3171 orntNew[1] = ornt[1]; 3172 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3173 orntNew[2] = 0; 3174 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 3175 orntNew[3] = ornt[3]; 3176 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 3177 orntNew[4] = ornt[4]; 3178 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3179 orntNew[5] = -3; 3180 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3181 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3182 #if 1 3183 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); 3184 for (p = 0; p < 6; ++p) { 3185 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); 3186 } 3187 #endif 3188 /* H hex */ 3189 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3190 orntNew[0] = -4; 3191 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 3192 orntNew[1] = ornt[1]; 3193 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3194 orntNew[2] = -1; 3195 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 3196 orntNew[3] = ornt[3]; 3197 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3198 orntNew[4] = 3; 3199 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 3200 orntNew[5] = ornt[5]; 3201 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3202 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3203 #if 1 3204 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); 3205 for (p = 0; p < 6; ++p) { 3206 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); 3207 } 3208 #endif 3209 } 3210 /* Split faces have 4 edges and the same cells as the parent */ 3211 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3212 ierr = PetscMalloc((4 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr); 3213 for (f = fStart; f < fEnd; ++f) { 3214 for (r = 0; r < 4; ++r) { 3215 /* TODO: This can come from GetFaces_Internal() */ 3216 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}; 3217 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 3218 const PetscInt *cone, *ornt, *support; 3219 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 3220 3221 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3222 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3223 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 3224 orntNew[(r+3)%4] = ornt[(r+3)%4]; 3225 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 3226 orntNew[(r+0)%4] = ornt[r]; 3227 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 3228 orntNew[(r+1)%4] = 0; 3229 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 3230 orntNew[(r+2)%4] = -2; 3231 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3232 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3233 #if 1 3234 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3235 for (p = 0; p < 4; ++p) { 3236 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); 3237 } 3238 #endif 3239 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3240 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3241 for (s = 0; s < supportSize; ++s) { 3242 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3243 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3244 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3245 for (c = 0; c < coneSize; ++c) { 3246 if (cone[c] == f) break; 3247 } 3248 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 3249 } 3250 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3251 #if 1 3252 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3253 for (p = 0; p < supportSize; ++p) { 3254 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); 3255 } 3256 #endif 3257 } 3258 } 3259 /* Interior faces have 4 edges and 2 cells */ 3260 for (c = cStart; c < cEnd; ++c) { 3261 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}; 3262 const PetscInt *cone, *ornt; 3263 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 3264 3265 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3266 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3267 /* A-D face */ 3268 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 3269 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 3270 orntNew[0] = 0; 3271 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3272 orntNew[1] = 0; 3273 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3274 orntNew[2] = -2; 3275 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 3276 orntNew[3] = -2; 3277 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3278 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3279 #if 1 3280 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3281 for (p = 0; p < 4; ++p) { 3282 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); 3283 } 3284 #endif 3285 /* C-D face */ 3286 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 3287 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 3288 orntNew[0] = 0; 3289 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3290 orntNew[1] = 0; 3291 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3292 orntNew[2] = -2; 3293 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 3294 orntNew[3] = -2; 3295 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3296 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3297 #if 1 3298 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3299 for (p = 0; p < 4; ++p) { 3300 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); 3301 } 3302 #endif 3303 /* B-C face */ 3304 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 3305 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 3306 orntNew[0] = -2; 3307 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 3308 orntNew[1] = 0; 3309 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3310 orntNew[2] = 0; 3311 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3312 orntNew[3] = -2; 3313 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3314 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3315 #if 1 3316 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3317 for (p = 0; p < 4; ++p) { 3318 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); 3319 } 3320 #endif 3321 /* A-B face */ 3322 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 3323 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 3324 orntNew[0] = -2; 3325 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 3326 orntNew[1] = 0; 3327 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3328 orntNew[2] = 0; 3329 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3330 orntNew[3] = -2; 3331 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3332 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3333 #if 1 3334 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3335 for (p = 0; p < 4; ++p) { 3336 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); 3337 } 3338 #endif 3339 /* E-F face */ 3340 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 3341 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3342 orntNew[0] = -2; 3343 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 3344 orntNew[1] = -2; 3345 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 3346 orntNew[2] = 0; 3347 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3348 orntNew[3] = 0; 3349 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3350 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3351 #if 1 3352 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3353 for (p = 0; p < 4; ++p) { 3354 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); 3355 } 3356 #endif 3357 /* F-G face */ 3358 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 3359 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3360 orntNew[0] = -2; 3361 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 3362 orntNew[1] = -2; 3363 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 3364 orntNew[2] = 0; 3365 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3366 orntNew[3] = 0; 3367 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3368 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3369 #if 1 3370 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3371 for (p = 0; p < 4; ++p) { 3372 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); 3373 } 3374 #endif 3375 /* G-H face */ 3376 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 3377 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 3378 orntNew[0] = -2; 3379 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 3380 orntNew[1] = 0; 3381 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3382 orntNew[2] = 0; 3383 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3384 orntNew[3] = -2; 3385 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3386 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3387 #if 1 3388 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3389 for (p = 0; p < 4; ++p) { 3390 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); 3391 } 3392 #endif 3393 /* E-H face */ 3394 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 3395 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3396 orntNew[0] = -2; 3397 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 3398 orntNew[1] = -2; 3399 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 3400 orntNew[2] = 0; 3401 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3402 orntNew[3] = 0; 3403 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3404 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3405 #if 1 3406 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3407 for (p = 0; p < 4; ++p) { 3408 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); 3409 } 3410 #endif 3411 /* A-E face */ 3412 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 3413 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 3414 orntNew[0] = 0; 3415 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3416 orntNew[1] = 0; 3417 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3418 orntNew[2] = -2; 3419 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 3420 orntNew[3] = -2; 3421 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3422 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3423 #if 1 3424 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3425 for (p = 0; p < 4; ++p) { 3426 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); 3427 } 3428 #endif 3429 /* D-F face */ 3430 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 3431 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 3432 orntNew[0] = -2; 3433 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 3434 orntNew[1] = 0; 3435 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3436 orntNew[2] = 0; 3437 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3438 orntNew[3] = -2; 3439 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3440 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3441 #if 1 3442 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3443 for (p = 0; p < 4; ++p) { 3444 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); 3445 } 3446 #endif 3447 /* C-G face */ 3448 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 3449 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3450 orntNew[0] = -2; 3451 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 3452 orntNew[1] = -2; 3453 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 3454 orntNew[2] = 0; 3455 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3456 orntNew[3] = 0; 3457 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3458 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3459 #if 1 3460 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3461 for (p = 0; p < 4; ++p) { 3462 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); 3463 } 3464 #endif 3465 /* B-H face */ 3466 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 3467 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3468 orntNew[0] = 0; 3469 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3470 orntNew[1] = -2; 3471 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 3472 orntNew[2] = -2; 3473 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 3474 orntNew[3] = 0; 3475 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3476 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3477 #if 1 3478 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3479 for (p = 0; p < 4; ++p) { 3480 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); 3481 } 3482 #endif 3483 for (r = 0; r < 12; ++r) { 3484 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 3485 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 3486 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 3487 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3488 #if 1 3489 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3490 for (p = 0; p < 2; ++p) { 3491 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); 3492 } 3493 #endif 3494 } 3495 } 3496 /* Split edges have 2 vertices and the same faces as the parent */ 3497 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3498 for (e = eStart; e < eEnd; ++e) { 3499 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3500 3501 for (r = 0; r < 2; ++r) { 3502 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3503 const PetscInt *cone, *ornt, *support; 3504 PetscInt coneNew[2], coneSize, c, supportSize, s; 3505 3506 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3507 coneNew[0] = vStartNew + (cone[0] - vStart); 3508 coneNew[1] = vStartNew + (cone[1] - vStart); 3509 coneNew[(r+1)%2] = newv; 3510 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3511 #if 1 3512 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3513 for (p = 0; p < 2; ++p) { 3514 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); 3515 } 3516 #endif 3517 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3518 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3519 for (s = 0; s < supportSize; ++s) { 3520 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3521 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3522 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3523 for (c = 0; c < coneSize; ++c) { 3524 if (cone[c] == e) break; 3525 } 3526 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 3527 } 3528 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3529 #if 1 3530 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3531 for (p = 0; p < supportSize; ++p) { 3532 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); 3533 } 3534 #endif 3535 } 3536 } 3537 /* Face edges have 2 vertices and 2+cells faces */ 3538 for (f = fStart; f < fEnd; ++f) { 3539 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}; 3540 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 3541 const PetscInt *cone, *coneCell, *orntCell, *support; 3542 PetscInt coneNew[2], coneSize, c, supportSize, s; 3543 3544 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3545 for (r = 0; r < 4; ++r) { 3546 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 3547 3548 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 3549 coneNew[1] = newv; 3550 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3551 #if 1 3552 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3553 for (p = 0; p < 2; ++p) { 3554 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); 3555 } 3556 #endif 3557 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3558 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3559 supportRef[0] = fStartNew + (f - fStart)*4 + r; 3560 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 3561 for (s = 0; s < supportSize; ++s) { 3562 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3563 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 3564 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 3565 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 3566 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 3567 } 3568 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3569 #if 1 3570 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3571 for (p = 0; p < 2+supportSize; ++p) { 3572 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); 3573 } 3574 #endif 3575 } 3576 } 3577 /* Cell edges have 2 vertices and 4 faces */ 3578 for (c = cStart; c < cEnd; ++c) { 3579 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}; 3580 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 3581 const PetscInt *cone; 3582 PetscInt coneNew[2], supportNew[4]; 3583 3584 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3585 for (r = 0; r < 6; ++r) { 3586 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 3587 3588 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 3589 coneNew[1] = newv; 3590 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3591 #if 1 3592 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3593 for (p = 0; p < 2; ++p) { 3594 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); 3595 } 3596 #endif 3597 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 3598 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3599 #if 1 3600 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3601 for (p = 0; p < 4; ++p) { 3602 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); 3603 } 3604 #endif 3605 } 3606 } 3607 /* Old vertices have identical supports */ 3608 for (v = vStart; v < vEnd; ++v) { 3609 const PetscInt newp = vStartNew + (v - vStart); 3610 const PetscInt *support, *cone; 3611 PetscInt size, s; 3612 3613 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3614 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3615 for (s = 0; s < size; ++s) { 3616 PetscInt r = 0; 3617 3618 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3619 if (cone[1] == v) r = 1; 3620 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3621 } 3622 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3623 #if 1 3624 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3625 for (p = 0; p < size; ++p) { 3626 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); 3627 } 3628 #endif 3629 } 3630 /* Edge vertices have 2 + faces supports */ 3631 for (e = eStart; e < eEnd; ++e) { 3632 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3633 const PetscInt *cone, *support; 3634 PetscInt size, s; 3635 3636 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3637 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3638 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3639 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3640 for (s = 0; s < size; ++s) { 3641 PetscInt r; 3642 3643 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3644 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 3645 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 3646 } 3647 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3648 #if 1 3649 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3650 for (p = 0; p < 2+size; ++p) { 3651 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); 3652 } 3653 #endif 3654 } 3655 /* Face vertices have 4 + cells supports */ 3656 for (f = fStart; f < fEnd; ++f) { 3657 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 3658 const PetscInt *cone, *support; 3659 PetscInt size, s; 3660 3661 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3662 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3663 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (e - eStart)*2 + (f - fStart)*4 + r; 3664 for (s = 0; s < size; ++s) { 3665 PetscInt r; 3666 3667 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3668 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 3669 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 3670 } 3671 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3672 #if 1 3673 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3674 for (p = 0; p < 4+size; ++p) { 3675 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); 3676 } 3677 #endif 3678 } 3679 /* Cell vertices have 6 supports */ 3680 for (c = cStart; c < cEnd; ++c) { 3681 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 3682 PetscInt supportNew[6]; 3683 3684 for (r = 0; r < 6; ++r) { 3685 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 3686 } 3687 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3688 } 3689 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3690 break; 3691 default: 3692 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 3693 } 3694 PetscFunctionReturn(0); 3695 } 3696 3697 #undef __FUNCT__ 3698 #define __FUNCT__ "CellRefinerSetCoordinates" 3699 PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 3700 { 3701 PetscSection coordSection, coordSectionNew; 3702 Vec coordinates, coordinatesNew; 3703 PetscScalar *coords, *coordsNew; 3704 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 3705 PetscInt dim, depth, coordSizeNew, cStart, cEnd, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 3706 PetscErrorCode ierr; 3707 3708 PetscFunctionBegin; 3709 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 3710 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3711 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 3712 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 3713 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 3714 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 3715 ierr = DMPlexGetHybridBounds(dm, NULL, &fMax, &eMax, NULL);CHKERRQ(ierr); 3716 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);} 3717 ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr); 3718 ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 3719 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 3720 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 3721 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dim);CHKERRQ(ierr); 3722 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 3723 if (fMax < 0) fMax = fEnd; 3724 if (eMax < 0) eMax = eEnd; 3725 /* All vertices have the dim coordinates */ 3726 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 3727 ierr = PetscSectionSetDof(coordSectionNew, v, dim);CHKERRQ(ierr); 3728 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dim);CHKERRQ(ierr); 3729 } 3730 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 3731 ierr = DMPlexSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr); 3732 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 3733 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 3734 ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr); 3735 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 3736 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 3737 ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr); 3738 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 3739 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 3740 switch (refiner) { 3741 case 0: break; 3742 case 6: /* Hex 3D */ 3743 /* Face vertices have the average of corner coordinates */ 3744 for (f = fStart; f < fEnd; ++f) { 3745 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 3746 PetscInt *cone = NULL; 3747 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 3748 3749 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3750 for (p = 0; p < closureSize*2; p += 2) { 3751 const PetscInt point = cone[p]; 3752 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 3753 } 3754 for (v = 0; v < coneSize; ++v) { 3755 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 3756 } 3757 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3758 for (d = 0; d < dim; ++d) { 3759 coordsNew[offnew+d] = 0.0; 3760 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 3761 coordsNew[offnew+d] /= coneSize; 3762 } 3763 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3764 } 3765 case 2: /* Hex 2D */ 3766 /* Cell vertices have the average of corner coordinates */ 3767 for (c = cStart; c < cEnd; ++c) { 3768 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (c - cStart) + (dim > 2 ? (fEnd - fStart) : 0); 3769 PetscInt *cone = NULL; 3770 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 3771 3772 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3773 for (p = 0; p < closureSize*2; p += 2) { 3774 const PetscInt point = cone[p]; 3775 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 3776 } 3777 for (v = 0; v < coneSize; ++v) { 3778 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 3779 } 3780 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3781 for (d = 0; d < dim; ++d) { 3782 coordsNew[offnew+d] = 0.0; 3783 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 3784 coordsNew[offnew+d] /= coneSize; 3785 } 3786 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 3787 } 3788 case 1: /* Simplicial 2D */ 3789 case 3: /* Hybrid Simplicial 2D */ 3790 case 5: /* Simplicial 3D */ 3791 case 7: /* Hybrid Simplicial 3D */ 3792 /* Edge vertices have the average of endpoint coordinates */ 3793 for (e = eStart; e < eMax; ++e) { 3794 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3795 const PetscInt *cone; 3796 PetscInt coneSize, offA, offB, offnew, d; 3797 3798 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 3799 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 3800 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3801 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 3802 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 3803 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3804 for (d = 0; d < dim; ++d) { 3805 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]); 3806 } 3807 } 3808 /* Old vertices have the same coordinates */ 3809 for (v = vStart; v < vEnd; ++v) { 3810 const PetscInt newv = vStartNew + (v - vStart); 3811 PetscInt off, offnew, d; 3812 3813 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 3814 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 3815 for (d = 0; d < dim; ++d) { 3816 coordsNew[offnew+d] = coords[off+d]; 3817 } 3818 } 3819 break; 3820 default: 3821 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 3822 } 3823 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 3824 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 3825 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 3826 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 3827 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 3828 PetscFunctionReturn(0); 3829 } 3830 3831 #undef __FUNCT__ 3832 #define __FUNCT__ "DMPlexCreateProcessSF" 3833 PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 3834 { 3835 PetscInt numRoots, numLeaves, l; 3836 const PetscInt *localPoints; 3837 const PetscSFNode *remotePoints; 3838 PetscInt *localPointsNew; 3839 PetscSFNode *remotePointsNew; 3840 PetscInt *ranks, *ranksNew; 3841 PetscErrorCode ierr; 3842 3843 PetscFunctionBegin; 3844 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 3845 ierr = PetscMalloc(numLeaves * sizeof(PetscInt), &ranks);CHKERRQ(ierr); 3846 for (l = 0; l < numLeaves; ++l) { 3847 ranks[l] = remotePoints[l].rank; 3848 } 3849 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 3850 ierr = PetscMalloc(numLeaves * sizeof(PetscInt), &ranksNew);CHKERRQ(ierr); 3851 ierr = PetscMalloc(numLeaves * sizeof(PetscInt), &localPointsNew);CHKERRQ(ierr); 3852 ierr = PetscMalloc(numLeaves * sizeof(PetscSFNode), &remotePointsNew);CHKERRQ(ierr); 3853 for (l = 0; l < numLeaves; ++l) { 3854 ranksNew[l] = ranks[l]; 3855 localPointsNew[l] = l; 3856 remotePointsNew[l].index = 0; 3857 remotePointsNew[l].rank = ranksNew[l]; 3858 } 3859 ierr = PetscFree(ranks);CHKERRQ(ierr); 3860 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr); 3861 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 3862 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 3863 ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 3864 PetscFunctionReturn(0); 3865 } 3866 3867 #undef __FUNCT__ 3868 #define __FUNCT__ "CellRefinerCreateSF" 3869 PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 3870 { 3871 PetscSF sf, sfNew, sfProcess; 3872 IS processRanks; 3873 MPI_Datatype depthType; 3874 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 3875 const PetscInt *localPoints, *neighbors; 3876 const PetscSFNode *remotePoints; 3877 PetscInt *localPointsNew; 3878 PetscSFNode *remotePointsNew; 3879 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 3880 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; 3881 PetscErrorCode ierr; 3882 3883 PetscFunctionBegin; 3884 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 3885 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3886 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 3887 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 3888 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 3889 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 3890 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 3891 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 3892 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 3893 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 3894 /* Caculate size of new SF */ 3895 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 3896 if (numRoots < 0) PetscFunctionReturn(0); 3897 for (l = 0; l < numLeaves; ++l) { 3898 const PetscInt p = localPoints[l]; 3899 3900 switch (refiner) { 3901 case 1: 3902 /* Simplicial 2D */ 3903 if ((p >= vStart) && (p < vEnd)) { 3904 /* Old vertices stay the same */ 3905 ++numLeavesNew; 3906 } else if ((p >= fStart) && (p < fEnd)) { 3907 /* Old faces add new faces and vertex */ 3908 numLeavesNew += 2 + 1; 3909 } else if ((p >= cStart) && (p < cEnd)) { 3910 /* Old cells add new cells and interior faces */ 3911 numLeavesNew += 4 + 3; 3912 } 3913 break; 3914 case 2: 3915 /* Hex 2D */ 3916 if ((p >= vStart) && (p < vEnd)) { 3917 /* Old vertices stay the same */ 3918 ++numLeavesNew; 3919 } else if ((p >= fStart) && (p < fEnd)) { 3920 /* Old faces add new faces and vertex */ 3921 numLeavesNew += 2 + 1; 3922 } else if ((p >= cStart) && (p < cEnd)) { 3923 /* Old cells add new cells, interior faces, and vertex */ 3924 numLeavesNew += 4 + 4 + 1; 3925 } 3926 break; 3927 case 5: 3928 /* Simplicial 3D */ 3929 if ((p >= vStart) && (p < vEnd)) { 3930 /* Old vertices stay the same */ 3931 ++numLeavesNew; 3932 } else if ((p >= eStart) && (p < eEnd)) { 3933 /* Old edges add new edges and vertex */ 3934 numLeavesNew += 2 + 1; 3935 } else if ((p >= fStart) && (p < fEnd)) { 3936 /* Old faces add new faces and face edges */ 3937 numLeavesNew += 4 + 3; 3938 } else if ((p >= cStart) && (p < cEnd)) { 3939 /* Old cells add new cells and interior faces and edges */ 3940 numLeavesNew += 8 + 8 + 1; 3941 } 3942 break; 3943 case 7: 3944 /* Hybrid Simplicial 3D */ 3945 if ((p >= vStart) && (p < vEnd)) { 3946 /* Interior vertices stay the same */ 3947 ++numLeavesNew; 3948 } else if ((p >= eStart) && (p < eMax)) { 3949 /* Interior edges add new edges and vertex */ 3950 numLeavesNew += 2 + 1; 3951 } else if ((p >= eMax) && (p < eEnd)) { 3952 /* Hybrid edges stay the same */ 3953 ++numLeavesNew; 3954 } else if ((p >= fStart) && (p < fMax)) { 3955 /* Interior faces add new faces and edges */ 3956 numLeavesNew += 4 + 3; 3957 } else if ((p >= fMax) && (p < fEnd)) { 3958 /* Hybrid faces add new faces and edges */ 3959 numLeavesNew += 2 + 1; 3960 } else if ((p >= cStart) && (p < cMax)) { 3961 /* Interior cells add new cells, faces, and edges */ 3962 numLeavesNew += 8 + 8 + 1; 3963 } else if ((p >= cMax) && (p < cEnd)) { 3964 /* Hybrid cells add new cells and faces */ 3965 numLeavesNew += 4 + 3; 3966 } 3967 break; 3968 case 6: 3969 /* Hex 3D */ 3970 if ((p >= vStart) && (p < vEnd)) { 3971 /* Old vertices stay the same */ 3972 ++numLeavesNew; 3973 } else if ((p >= eStart) && (p < eEnd)) { 3974 /* Old edges add new edges, and vertex */ 3975 numLeavesNew += 2 + 1; 3976 } else if ((p >= fStart) && (p < fEnd)) { 3977 /* Old faces add new faces, edges, and vertex */ 3978 numLeavesNew += 4 + 4 + 1; 3979 } else if ((p >= cStart) && (p < cEnd)) { 3980 /* Old cells add new cells, faces, edges, and vertex */ 3981 numLeavesNew += 8 + 12 + 6 + 1; 3982 } 3983 break; 3984 default: 3985 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 3986 } 3987 } 3988 /* Communicate depthSizes for each remote rank */ 3989 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 3990 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 3991 ierr = PetscMalloc5((depth+1)*numNeighbors,PetscInt,&rdepthSize,numNeighbors,PetscInt,&rvStartNew,numNeighbors,PetscInt,&reStartNew,numNeighbors,PetscInt,&rfStartNew,numNeighbors,PetscInt,&rcStartNew);CHKERRQ(ierr); 3992 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); 3993 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 3994 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 3995 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 3996 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 3997 for (n = 0; n < numNeighbors; ++n) { 3998 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 3999 } 4000 depthSizeOld[depth] = cMax; 4001 depthSizeOld[0] = vMax; 4002 depthSizeOld[depth-1] = fMax; 4003 depthSizeOld[1] = eMax; 4004 4005 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 4006 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 4007 4008 depthSizeOld[depth] = cEnd - cStart; 4009 depthSizeOld[0] = vEnd - vStart; 4010 depthSizeOld[depth-1] = fEnd - fStart; 4011 depthSizeOld[1] = eEnd - eStart; 4012 4013 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 4014 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 4015 for (n = 0; n < numNeighbors; ++n) { 4016 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 4017 } 4018 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 4019 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 4020 /* Calculate new point SF */ 4021 ierr = PetscMalloc(numLeavesNew * sizeof(PetscInt), &localPointsNew);CHKERRQ(ierr); 4022 ierr = PetscMalloc(numLeavesNew * sizeof(PetscSFNode), &remotePointsNew);CHKERRQ(ierr); 4023 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 4024 for (l = 0, m = 0; l < numLeaves; ++l) { 4025 PetscInt p = localPoints[l]; 4026 PetscInt rp = remotePoints[l].index, n; 4027 PetscMPIInt rrank = remotePoints[l].rank; 4028 4029 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 4030 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 4031 switch (refiner) { 4032 case 1: 4033 /* Simplicial 2D */ 4034 if ((p >= vStart) && (p < vEnd)) { 4035 /* Old vertices stay the same */ 4036 localPointsNew[m] = vStartNew + (p - vStart); 4037 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4038 remotePointsNew[m].rank = rrank; 4039 ++m; 4040 } else if ((p >= fStart) && (p < fEnd)) { 4041 /* Old faces add new faces and vertex */ 4042 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 4043 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 4044 remotePointsNew[m].rank = rrank; 4045 ++m; 4046 for (r = 0; r < 2; ++r, ++m) { 4047 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 4048 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 4049 remotePointsNew[m].rank = rrank; 4050 } 4051 } else if ((p >= cStart) && (p < cEnd)) { 4052 /* Old cells add new cells and interior faces */ 4053 for (r = 0; r < 4; ++r, ++m) { 4054 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4055 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4056 remotePointsNew[m].rank = rrank; 4057 } 4058 for (r = 0; r < 3; ++r, ++m) { 4059 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 4060 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 4061 remotePointsNew[m].rank = rrank; 4062 } 4063 } 4064 break; 4065 case 2: 4066 /* Hex 2D */ 4067 if ((p >= vStart) && (p < vEnd)) { 4068 /* Old vertices stay the same */ 4069 localPointsNew[m] = vStartNew + (p - vStart); 4070 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4071 remotePointsNew[m].rank = rrank; 4072 ++m; 4073 } else if ((p >= fStart) && (p < fEnd)) { 4074 /* Old faces add new faces and vertex */ 4075 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 4076 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 4077 remotePointsNew[m].rank = rrank; 4078 ++m; 4079 for (r = 0; r < 2; ++r, ++m) { 4080 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 4081 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 4082 remotePointsNew[m].rank = rrank; 4083 } 4084 } else if ((p >= cStart) && (p < cEnd)) { 4085 /* Old cells add new cells, interior faces, and vertex */ 4086 for (r = 0; r < 4; ++r, ++m) { 4087 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4088 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4089 remotePointsNew[m].rank = rrank; 4090 } 4091 for (r = 0; r < 4; ++r, ++m) { 4092 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 4093 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r; 4094 remotePointsNew[m].rank = rrank; 4095 } 4096 for (r = 0; r < 1; ++r, ++m) { 4097 localPointsNew[m] = vStartNew + (fEnd - fStart) + (p - cStart) + r; 4098 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 4099 remotePointsNew[m].rank = rrank; 4100 } 4101 } 4102 break; 4103 case 3: 4104 /* Hybrid simplicial 2D */ 4105 if ((p >= vStart) && (p < vEnd)) { 4106 /* Old vertices stay the same */ 4107 localPointsNew[m] = vStartNew + (p - vStart); 4108 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4109 remotePointsNew[m].rank = rrank; 4110 ++m; 4111 } else if ((p >= fStart) && (p < fMax)) { 4112 /* Old interior faces add new faces and vertex */ 4113 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 4114 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 4115 remotePointsNew[m].rank = rrank; 4116 ++m; 4117 for (r = 0; r < 2; ++r, ++m) { 4118 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 4119 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 4120 remotePointsNew[m].rank = rrank; 4121 } 4122 } else if ((p >= fMax) && (p < fEnd)) { 4123 /* Old hybrid faces stay the same */ 4124 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 4125 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 4126 remotePointsNew[m].rank = rrank; 4127 ++m; 4128 } else if ((p >= cStart) && (p < cMax)) { 4129 /* Old interior cells add new cells and interior faces */ 4130 for (r = 0; r < 4; ++r, ++m) { 4131 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4132 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4133 remotePointsNew[m].rank = rrank; 4134 } 4135 for (r = 0; r < 3; ++r, ++m) { 4136 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 4137 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 4138 remotePointsNew[m].rank = rrank; 4139 } 4140 } else if ((p >= cStart) && (p < cMax)) { 4141 /* Old hybrid cells add new cells and hybrid face */ 4142 for (r = 0; r < 2; ++r, ++m) { 4143 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 4144 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 4145 remotePointsNew[m].rank = rrank; 4146 } 4147 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 4148 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]); 4149 remotePointsNew[m].rank = rrank; 4150 ++m; 4151 } 4152 break; 4153 case 5: 4154 /* Simplicial 3D */ 4155 if ((p >= vStart) && (p < vEnd)) { 4156 /* Old vertices stay the same */ 4157 localPointsNew[m] = vStartNew + (p - vStart); 4158 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4159 remotePointsNew[m].rank = rrank; 4160 ++m; 4161 } else if ((p >= eStart) && (p < eEnd)) { 4162 /* Old edges add new edges and vertex */ 4163 for (r = 0; r < 2; ++r, ++m) { 4164 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 4165 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 4166 remotePointsNew[m].rank = rrank; 4167 } 4168 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 4169 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 4170 remotePointsNew[m].rank = rrank; 4171 ++m; 4172 } else if ((p >= fStart) && (p < fEnd)) { 4173 /* Old faces add new faces and face edges */ 4174 for (r = 0; r < 4; ++r, ++m) { 4175 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 4176 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 4177 remotePointsNew[m].rank = rrank; 4178 } 4179 for (r = 0; r < 3; ++r, ++m) { 4180 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 4181 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*3 + r; 4182 remotePointsNew[m].rank = rrank; 4183 } 4184 } else if ((p >= cStart) && (p < cEnd)) { 4185 /* Old cells add new cells and interior faces and edges */ 4186 for (r = 0; r < 8; ++r, ++m) { 4187 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 4188 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 4189 remotePointsNew[m].rank = rrank; 4190 } 4191 for (r = 0; r < 8; ++r, ++m) { 4192 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 4193 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*8 + r; 4194 remotePointsNew[m].rank = rrank; 4195 } 4196 for (r = 0; r < 1; ++r, ++m) { 4197 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 4198 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*1 + r; 4199 remotePointsNew[m].rank = rrank; 4200 } 4201 } 4202 break; 4203 case 7: 4204 /* Hybrid Simplicial 3D */ 4205 if ((p >= vStart) && (p < vEnd)) { 4206 /* Interior vertices stay the same */ 4207 localPointsNew[m] = vStartNew + (p - vStart); 4208 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4209 remotePointsNew[m].rank = rrank; 4210 ++m; 4211 } else if ((p >= eStart) && (p < eMax)) { 4212 /* Interior edges add new edges and vertex */ 4213 for (r = 0; r < 2; ++r, ++m) { 4214 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 4215 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 4216 remotePointsNew[m].rank = rrank; 4217 } 4218 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 4219 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 4220 remotePointsNew[m].rank = rrank; 4221 ++m; 4222 } else if ((p >= eMax) && (p < eEnd)) { 4223 /* Hybrid edges stay the same */ 4224 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 4225 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]); 4226 remotePointsNew[m].rank = rrank; 4227 ++m; 4228 } else if ((p >= fStart) && (p < fMax)) { 4229 /* Interior faces add new faces and edges */ 4230 for (r = 0; r < 4; ++r, ++m) { 4231 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 4232 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 4233 remotePointsNew[m].rank = rrank; 4234 } 4235 for (r = 0; r < 3; ++r, ++m) { 4236 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 4237 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 4238 remotePointsNew[m].rank = rrank; 4239 } 4240 } else if ((p >= fMax) && (p < fEnd)) { 4241 /* Hybrid faces add new faces and edges */ 4242 for (r = 0; r < 2; ++r, ++m) { 4243 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fStart)*2 + r; 4244 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; 4245 remotePointsNew[m].rank = rrank; 4246 } 4247 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart) + (cMax - cStart) + (fEnd - fMax); 4248 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]); 4249 remotePointsNew[m].rank = rrank; 4250 } else if ((p >= cStart) && (p < cMax)) { 4251 /* Interior cells add new cells, faces, and edges */ 4252 for (r = 0; r < 8; ++r, ++m) { 4253 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 4254 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 4255 remotePointsNew[m].rank = rrank; 4256 } 4257 for (r = 0; r < 8; ++r, ++m) { 4258 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 4259 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 4260 remotePointsNew[m].rank = rrank; 4261 } 4262 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + r; 4263 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; 4264 remotePointsNew[m].rank = rrank; 4265 } else if ((p >= cMax) && (p < cEnd)) { 4266 /* Hybrid cells add new cells and faces */ 4267 for (r = 0; r < 4; ++r, ++m) { 4268 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 4269 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 4270 remotePointsNew[m].rank = rrank; 4271 } 4272 for (r = 0; r < 3; ++r, ++m) { 4273 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*4 + (p - cMax)*3 + r; 4274 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; 4275 remotePointsNew[m].rank = rrank; 4276 } 4277 } 4278 break; 4279 case 6: 4280 /* Hex 3D */ 4281 if ((p >= vStart) && (p < vEnd)) { 4282 /* Old vertices stay the same */ 4283 localPointsNew[m] = vStartNew + (p - vStart); 4284 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 4285 remotePointsNew[m].rank = rrank; 4286 ++m; 4287 } else if ((p >= eStart) && (p < eEnd)) { 4288 /* Old edges add new edges and vertex */ 4289 for (r = 0; r < 2; ++r, ++m) { 4290 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 4291 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 4292 remotePointsNew[m].rank = rrank; 4293 } 4294 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 4295 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 4296 remotePointsNew[m].rank = rrank; 4297 ++m; 4298 } else if ((p >= fStart) && (p < fEnd)) { 4299 /* Old faces add new faces, edges, and vertex */ 4300 for (r = 0; r < 4; ++r, ++m) { 4301 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 4302 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 4303 remotePointsNew[m].rank = rrank; 4304 } 4305 for (r = 0; r < 4; ++r, ++m) { 4306 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 4307 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*4 + r; 4308 remotePointsNew[m].rank = rrank; 4309 } 4310 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 4311 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]); 4312 remotePointsNew[m].rank = rrank; 4313 ++m; 4314 } else if ((p >= cStart) && (p < cEnd)) { 4315 /* Old cells add new cells, faces, edges, and vertex */ 4316 for (r = 0; r < 8; ++r, ++m) { 4317 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 4318 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 4319 remotePointsNew[m].rank = rrank; 4320 } 4321 for (r = 0; r < 12; ++r, ++m) { 4322 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 4323 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*12 + r; 4324 remotePointsNew[m].rank = rrank; 4325 } 4326 for (r = 0; r < 6; ++r, ++m) { 4327 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 4328 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*6 + r; 4329 remotePointsNew[m].rank = rrank; 4330 } 4331 for (r = 0; r < 1; ++r, ++m) { 4332 localPointsNew[m] = vStartNew + (eEnd - eStart) + (fEnd - fStart) + (p - cStart) + r; 4333 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 4334 remotePointsNew[m].rank = rrank; 4335 } 4336 } 4337 break; 4338 default: 4339 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 4340 } 4341 } 4342 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 4343 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 4344 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 4345 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 4346 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 4347 PetscFunctionReturn(0); 4348 } 4349 4350 #undef __FUNCT__ 4351 #define __FUNCT__ "CellRefinerCreateLabels" 4352 PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 4353 { 4354 PetscInt numLabels, l; 4355 PetscInt depth, newp, cStart, cStartNew = 0, cEnd, cMax, vStart, vStartNew = 0, vEnd, vMax, fStart, fStartNew = 0, fEnd, fMax, eStart, eStartNew = 0, eEnd, eMax, r; 4356 PetscErrorCode ierr; 4357 4358 PetscFunctionBegin; 4359 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 4360 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 4361 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 4362 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 4363 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 4364 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 4365 ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 4366 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 4367 switch (refiner) { 4368 case 0: break; 4369 case 7: 4370 case 8: 4371 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 4372 case 3: 4373 case 4: 4374 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 4375 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 4376 } 4377 for (l = 0; l < numLabels; ++l) { 4378 DMLabel label, labelNew; 4379 const char *lname; 4380 PetscBool isDepth; 4381 IS valueIS; 4382 const PetscInt *values; 4383 PetscInt numValues, val; 4384 4385 ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr); 4386 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 4387 if (isDepth) continue; 4388 ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr); 4389 ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr); 4390 ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 4391 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 4392 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 4393 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 4394 for (val = 0; val < numValues; ++val) { 4395 IS pointIS; 4396 const PetscInt *points; 4397 PetscInt numPoints, n; 4398 4399 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 4400 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 4401 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 4402 for (n = 0; n < numPoints; ++n) { 4403 const PetscInt p = points[n]; 4404 switch (refiner) { 4405 case 1: 4406 /* Simplicial 2D */ 4407 if ((p >= vStart) && (p < vEnd)) { 4408 /* Old vertices stay the same */ 4409 newp = vStartNew + (p - vStart); 4410 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4411 } else if ((p >= fStart) && (p < fEnd)) { 4412 /* Old faces add new faces and vertex */ 4413 newp = vStartNew + (vEnd - vStart) + (p - fStart); 4414 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4415 for (r = 0; r < 2; ++r) { 4416 newp = fStartNew + (p - fStart)*2 + r; 4417 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4418 } 4419 } else if ((p >= cStart) && (p < cEnd)) { 4420 /* Old cells add new cells and interior faces */ 4421 for (r = 0; r < 4; ++r) { 4422 newp = cStartNew + (p - cStart)*4 + r; 4423 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4424 } 4425 for (r = 0; r < 3; ++r) { 4426 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 4427 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4428 } 4429 } 4430 break; 4431 case 2: 4432 /* Hex 2D */ 4433 if ((p >= vStart) && (p < vEnd)) { 4434 /* Old vertices stay the same */ 4435 newp = vStartNew + (p - vStart); 4436 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4437 } else if ((p >= fStart) && (p < fEnd)) { 4438 /* Old faces add new faces and vertex */ 4439 newp = vStartNew + (vEnd - vStart) + (p - fStart); 4440 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4441 for (r = 0; r < 2; ++r) { 4442 newp = fStartNew + (p - fStart)*2 + r; 4443 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4444 } 4445 } else if ((p >= cStart) && (p < cEnd)) { 4446 /* Old cells add new cells and interior faces and vertex */ 4447 for (r = 0; r < 4; ++r) { 4448 newp = cStartNew + (p - cStart)*4 + r; 4449 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4450 } 4451 for (r = 0; r < 4; ++r) { 4452 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 4453 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4454 } 4455 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 4456 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4457 } 4458 break; 4459 case 3: 4460 /* Hybrid simplicial 2D */ 4461 if ((p >= vStart) && (p < vEnd)) { 4462 /* Old vertices stay the same */ 4463 newp = vStartNew + (p - vStart); 4464 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4465 } else if ((p >= fStart) && (p < fMax)) { 4466 /* Old interior faces add new faces and vertex */ 4467 newp = vStartNew + (vEnd - vStart) + (p - fStart); 4468 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4469 for (r = 0; r < 2; ++r) { 4470 newp = fStartNew + (p - fStart)*2 + r; 4471 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4472 } 4473 } else if ((p >= fMax) && (p < fEnd)) { 4474 /* Old hybrid faces stay the same */ 4475 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 4476 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4477 } else if ((p >= cStart) && (p < cMax)) { 4478 /* Old interior cells add new cells and interior faces */ 4479 for (r = 0; r < 4; ++r) { 4480 newp = cStartNew + (p - cStart)*4 + r; 4481 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4482 } 4483 for (r = 0; r < 3; ++r) { 4484 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 4485 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4486 } 4487 } else if ((p >= cMax) && (p < cEnd)) { 4488 /* Old hybrid cells add new cells and hybrid face */ 4489 for (r = 0; r < 2; ++r) { 4490 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 4491 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4492 } 4493 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 4494 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4495 } 4496 break; 4497 case 5: 4498 /* Simplicial 3D */ 4499 if ((p >= vStart) && (p < vEnd)) { 4500 /* Old vertices stay the same */ 4501 newp = vStartNew + (p - vStart); 4502 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4503 } else if ((p >= eStart) && (p < eEnd)) { 4504 /* Old edges add new edges and vertex */ 4505 for (r = 0; r < 2; ++r) { 4506 newp = eStartNew + (p - eStart)*2 + r; 4507 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4508 } 4509 newp = vStartNew + (vEnd - vStart) + (p - eStart); 4510 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4511 } else if ((p >= fStart) && (p < fEnd)) { 4512 /* Old faces add new faces and edges */ 4513 for (r = 0; r < 4; ++r) { 4514 newp = fStartNew + (p - fStart)*4 + r; 4515 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4516 } 4517 for (r = 0; r < 3; ++r) { 4518 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 4519 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4520 } 4521 } else if ((p >= cStart) && (p < cEnd)) { 4522 /* Old cells add new cells and interior faces and edges */ 4523 for (r = 0; r < 8; ++r) { 4524 newp = cStartNew + (p - cStart)*8 + r; 4525 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4526 } 4527 for (r = 0; r < 8; ++r) { 4528 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 4529 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4530 } 4531 for (r = 0; r < 1; ++r) { 4532 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 4533 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4534 } 4535 } 4536 break; 4537 case 7: 4538 /* Hybrid Simplicial 3D */ 4539 if ((p >= vStart) && (p < vEnd)) { 4540 /* Interior vertices stay the same */ 4541 newp = vStartNew + (p - vStart); 4542 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4543 } else if ((p >= eStart) && (p < eMax)) { 4544 /* Interior edges add new edges and vertex */ 4545 for (r = 0; r < 2; ++r) { 4546 newp = eStartNew + (p - eStart)*2 + r; 4547 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4548 } 4549 newp = vStartNew + (vEnd - vStart) + (p - eStart); 4550 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4551 } else if ((p >= eMax) && (p < eEnd)) { 4552 /* Hybrid edges stay the same */ 4553 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 4554 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4555 } else if ((p >= fStart) && (p < fMax)) { 4556 /* Interior faces add new faces and edges */ 4557 for (r = 0; r < 4; ++r) { 4558 newp = fStartNew + (p - fStart)*4 + r; 4559 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4560 } 4561 for (r = 0; r < 3; ++r) { 4562 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 4563 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4564 } 4565 } else if ((p >= fMax) && (p < fEnd)) { 4566 /* Hybrid faces add new faces and edges */ 4567 for (r = 0; r < 2; ++r) { 4568 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 4569 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4570 } 4571 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 4572 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4573 } else if ((p >= cStart) && (p < cMax)) { 4574 /* Interior cells add new cells, faces, and edges */ 4575 for (r = 0; r < 8; ++r) { 4576 newp = cStartNew + (p - cStart)*8 + r; 4577 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4578 } 4579 for (r = 0; r < 8; ++r) { 4580 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 4581 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4582 } 4583 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 4584 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4585 } else if ((p >= cMax) && (p < cEnd)) { 4586 /* Hybrid cells add new cells and faces */ 4587 for (r = 0; r < 4; ++r) { 4588 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 4589 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4590 } 4591 for (r = 0; r < 3; ++r) { 4592 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 4593 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4594 } 4595 } 4596 break; 4597 case 6: 4598 /* Hex 3D */ 4599 if ((p >= vStart) && (p < vEnd)) { 4600 /* Old vertices stay the same */ 4601 newp = vStartNew + (p - vStart); 4602 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4603 } else if ((p >= eStart) && (p < eEnd)) { 4604 /* Old edges add new edges and vertex */ 4605 for (r = 0; r < 2; ++r) { 4606 newp = eStartNew + (p - eStart)*2 + r; 4607 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4608 } 4609 newp = vStartNew + (vEnd - vStart) + (p - eStart); 4610 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4611 } else if ((p >= fStart) && (p < fEnd)) { 4612 /* Old faces add new faces, edges, and vertex */ 4613 for (r = 0; r < 4; ++r) { 4614 newp = fStartNew + (p - fStart)*4 + r; 4615 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4616 } 4617 for (r = 0; r < 4; ++r) { 4618 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 4619 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4620 } 4621 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 4622 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4623 } else if ((p >= cStart) && (p < cEnd)) { 4624 /* Old cells add new cells, faces, edges, and vertex */ 4625 for (r = 0; r < 8; ++r) { 4626 newp = cStartNew + (p - cStart)*8 + r; 4627 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4628 } 4629 for (r = 0; r < 12; ++r) { 4630 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 4631 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4632 } 4633 for (r = 0; r < 6; ++r) { 4634 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 4635 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4636 } 4637 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 4638 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 4639 } 4640 break; 4641 default: 4642 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 4643 } 4644 } 4645 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 4646 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 4647 } 4648 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 4649 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 4650 if (0) { 4651 ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr); 4652 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 4653 ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 4654 } 4655 } 4656 PetscFunctionReturn(0); 4657 } 4658 4659 #undef __FUNCT__ 4660 #define __FUNCT__ "DMPlexRefineUniform_Internal" 4661 /* This will only work for interpolated meshes */ 4662 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 4663 { 4664 DM rdm; 4665 PetscInt *depthSize; 4666 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 4667 PetscErrorCode ierr; 4668 4669 PetscFunctionBegin; 4670 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 4671 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 4672 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 4673 ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr); 4674 /* Calculate number of new points of each depth */ 4675 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 4676 ierr = PetscMalloc((depth+1) * sizeof(PetscInt), &depthSize);CHKERRQ(ierr); 4677 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 4678 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 4679 /* Step 1: Set chart */ 4680 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 4681 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 4682 /* Step 2: Set cone/support sizes */ 4683 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4684 /* Step 3: Setup refined DM */ 4685 ierr = DMSetUp(rdm);CHKERRQ(ierr); 4686 /* Step 4: Set cones and supports */ 4687 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4688 /* Step 5: Stratify */ 4689 ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 4690 /* Step 6: Set coordinates for vertices */ 4691 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4692 /* Step 7: Create pointSF */ 4693 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4694 /* Step 8: Create labels */ 4695 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 4696 ierr = PetscFree(depthSize);CHKERRQ(ierr); 4697 4698 *dmRefined = rdm; 4699 PetscFunctionReturn(0); 4700 } 4701 4702 #undef __FUNCT__ 4703 #define __FUNCT__ "DMPlexSetRefinementUniform" 4704 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 4705 { 4706 DM_Plex *mesh = (DM_Plex*) dm->data; 4707 4708 PetscFunctionBegin; 4709 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4710 mesh->refinementUniform = refinementUniform; 4711 PetscFunctionReturn(0); 4712 } 4713 4714 #undef __FUNCT__ 4715 #define __FUNCT__ "DMPlexGetRefinementUniform" 4716 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 4717 { 4718 DM_Plex *mesh = (DM_Plex*) dm->data; 4719 4720 PetscFunctionBegin; 4721 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4722 PetscValidPointer(refinementUniform, 2); 4723 *refinementUniform = mesh->refinementUniform; 4724 PetscFunctionReturn(0); 4725 } 4726 4727 #undef __FUNCT__ 4728 #define __FUNCT__ "DMPlexSetRefinementLimit" 4729 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 4730 { 4731 DM_Plex *mesh = (DM_Plex*) dm->data; 4732 4733 PetscFunctionBegin; 4734 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4735 mesh->refinementLimit = refinementLimit; 4736 PetscFunctionReturn(0); 4737 } 4738 4739 #undef __FUNCT__ 4740 #define __FUNCT__ "DMPlexGetRefinementLimit" 4741 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 4742 { 4743 DM_Plex *mesh = (DM_Plex*) dm->data; 4744 4745 PetscFunctionBegin; 4746 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4747 PetscValidPointer(refinementLimit, 2); 4748 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 4749 *refinementLimit = mesh->refinementLimit; 4750 PetscFunctionReturn(0); 4751 } 4752 4753 #undef __FUNCT__ 4754 #define __FUNCT__ "DMPlexGetCellRefiner_Internal" 4755 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 4756 { 4757 PetscInt dim, cStart, cEnd, coneSize, cMax; 4758 PetscErrorCode ierr; 4759 4760 PetscFunctionBegin; 4761 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 4762 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 4763 if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);} 4764 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 4765 ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 4766 switch (dim) { 4767 case 2: 4768 switch (coneSize) { 4769 case 3: 4770 if (cMax >= 0) *cellRefiner = 3; /* Hybrid */ 4771 else *cellRefiner = 1; /* Triangular */ 4772 break; 4773 case 4: 4774 if (cMax >= 0) *cellRefiner = 4; /* Hybrid */ 4775 else *cellRefiner = 2; /* Quadrilateral */ 4776 break; 4777 default: 4778 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 4779 } 4780 break; 4781 case 3: 4782 switch (coneSize) { 4783 case 4: 4784 if (cMax >= 0) *cellRefiner = 7; /* Hybrid */ 4785 else *cellRefiner = 5; /* Tetrahedral */ 4786 break; 4787 case 6: 4788 if (cMax >= 0) *cellRefiner = 8; /* Hybrid */ 4789 else *cellRefiner = 6; /* hexahedral */ 4790 break; 4791 default: 4792 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 4793 } 4794 break; 4795 default: 4796 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 4797 } 4798 PetscFunctionReturn(0); 4799 } 4800