1 #include <petsc-private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2 #include <petscsf.h> 3 4 #undef __FUNCT__ 5 #define __FUNCT__ "GetDepthStart_Private" 6 PETSC_STATIC_INLINE PetscErrorCode GetDepthStart_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cStart, PetscInt *fStart, PetscInt *eStart, PetscInt *vStart) 7 { 8 PetscFunctionBegin; 9 if (cStart) *cStart = 0; 10 if (vStart) *vStart = depthSize[depth]; 11 if (fStart) *fStart = depthSize[depth] + depthSize[0]; 12 if (eStart) *eStart = depthSize[depth] + depthSize[0] + depthSize[depth-1]; 13 PetscFunctionReturn(0); 14 } 15 16 #undef __FUNCT__ 17 #define __FUNCT__ "GetDepthEnd_Private" 18 PETSC_STATIC_INLINE PetscErrorCode GetDepthEnd_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cEnd, PetscInt *fEnd, PetscInt *eEnd, PetscInt *vEnd) 19 { 20 PetscFunctionBegin; 21 if (cEnd) *cEnd = depthSize[depth]; 22 if (vEnd) *vEnd = depthSize[depth] + depthSize[0]; 23 if (fEnd) *fEnd = depthSize[depth] + depthSize[0] + depthSize[depth-1]; 24 if (eEnd) *eEnd = depthSize[depth] + depthSize[0] + depthSize[depth-1] + depthSize[1]; 25 PetscFunctionReturn(0); 26 } 27 28 #undef __FUNCT__ 29 #define __FUNCT__ "CellRefinerGetSizes" 30 static PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[]) 31 { 32 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 33 PetscErrorCode ierr; 34 35 PetscFunctionBegin; 36 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 37 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 38 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 39 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 40 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 41 switch (refiner) { 42 case 0: 43 break; 44 case 1: 45 /* Simplicial 2D */ 46 depthSize[0] = vEnd - vStart + fEnd - fStart; /* Add a vertex on every face */ 47 depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */ 48 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 49 break; 50 case 3: 51 /* Hybrid Simplicial 2D */ 52 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 53 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 54 depthSize[0] = vEnd - vStart + fMax - fStart; /* Add a vertex on every face, but not hybrid faces */ 55 depthSize[1] = 2*(fMax - fStart) + 3*(cMax - cStart) + (fEnd - fMax) + (cEnd - cMax); /* Every interior face is split into 2 faces, 3 faces are added for each interior cell, and one in each hybrid cell */ 56 depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax); /* Interior cells split into 4 cells, Hybrid cells split into 2 cells */ 57 break; 58 case 2: 59 /* Hex 2D */ 60 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* 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 4: 65 /* Hybrid Hex 2D */ 66 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 67 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 68 /* Quadrilateral */ 69 depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart; /* Add a vertex on every face and cell */ 70 depthSize[1] = 2*(fMax - fStart) + 4*(cMax - cStart); /* Every face is split into 2 faces, and 4 faces are added for each cell */ 71 depthSize[2] = 4*(cMax - cStart); /* Every cell split into 4 cells */ 72 /* Segment Prisms */ 73 depthSize[0] += 0; /* No hybrid vertices */ 74 depthSize[1] += (fEnd - fMax) + (cEnd - cMax); /* Every hybrid face remains and 1 faces is added for each hybrid cell */ 75 depthSize[2] += 2*(cEnd - cMax); /* Every hybrid cell split into 2 cells */ 76 break; 77 case 5: 78 /* Simplicial 3D */ 79 depthSize[0] = vEnd - vStart + eEnd - eStart; /* Add a vertex on every edge */ 80 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 */ 81 depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart); /* Every face split into 4 faces and 8 faces are added for each cell */ 82 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 83 break; 84 case 7: 85 /* Hybrid Simplicial 3D */ 86 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 87 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 88 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 89 /* Tetrahedra */ 90 depthSize[0] = vEnd - vStart + eMax - eStart; /* Add a vertex on every interior edge */ 91 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 */ 92 depthSize[2] = 4*(fMax - fStart) + 8*(cMax - cStart); /* Every interior face split into 4 faces, 8 faces added for each interior cell */ 93 depthSize[3] = 8*(cMax - cStart); /* Every interior cell split into 8 cells */ 94 /* Triangular Prisms */ 95 depthSize[0] += 0; /* No hybrid vertices */ 96 depthSize[1] += (eEnd - eMax) + (fEnd - fMax); /* Every hybrid edge remains, 1 edge for every hybrid face */ 97 depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */ 98 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 99 break; 100 case 6: 101 /* Hex 3D */ 102 depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */ 103 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 */ 104 depthSize[2] = 4*(fEnd - fStart) + 12*(cEnd - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 105 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 106 break; 107 case 8: 108 /* Hybrid Hex 3D */ 109 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 110 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 111 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 112 /* Hexahedra */ 113 depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */ 114 depthSize[1] = 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart); /* Every edge is split into 2 edge, 4 edges are added for each face, and 6 edges for each cell */ 115 depthSize[2] = 4*(fMax - fStart) + 12*(cMax - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 116 depthSize[3] = 8*(cMax - cStart); /* Every cell split into 8 cells */ 117 /* Quadrilateral Prisms */ 118 depthSize[0] += 0; /* No hybrid vertices */ 119 depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */ 120 depthSize[2] += 2*(fEnd - fMax) + 4*(cEnd - cMax); /* Every hybrid face split into 2 faces and 4 faces are added for each hybrid cell */ 121 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 122 break; 123 default: 124 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 125 } 126 PetscFunctionReturn(0); 127 } 128 129 /* Return triangle edge for orientation o, if it is r for o == 0 */ 130 PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) { 131 return (o < 0 ? 2-(o+r) : o+r)%3; 132 } 133 PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) { 134 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 135 } 136 137 /* Return triangle subface for orientation o, if it is r for o == 0 */ 138 PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) { 139 return (o < 0 ? 3-(o+r) : o+r)%3; 140 } 141 PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) { 142 return (o < 0 ? 3-(o+s) : 3+s-o)%3; 143 } 144 145 /* I HAVE NO IDEA: Return ??? for orientation o, if it is r for o == 0 */ 146 PETSC_STATIC_INLINE PetscInt GetTetSomething_Static(PetscInt o, PetscInt r) { 147 return (o < 0 ? 1-(o+r) : o+r)%3; 148 } 149 PETSC_STATIC_INLINE PetscInt GetTetSomethingInverse_Static(PetscInt o, PetscInt s) { 150 return (o < 0 ? 1-(o+s) : 3+s-o)%3; 151 } 152 153 154 /* Return quad edge for orientation o, if it is r for o == 0 */ 155 PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) { 156 return (o < 0 ? 3-(o+r) : o+r)%4; 157 } 158 PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) { 159 return (o < 0 ? 3-(o+s) : 4+s-o)%4; 160 } 161 162 /* Return quad subface for orientation o, if it is r for o == 0 */ 163 PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) { 164 return (o < 0 ? 4-(o+r) : o+r)%4; 165 } 166 PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) { 167 return (o < 0 ? 4-(o+s) : 4+s-o)%4; 168 } 169 170 #undef __FUNCT__ 171 #define __FUNCT__ "CellRefinerSetConeSizes" 172 static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 173 { 174 PetscInt depth, cStart, cStartNew, cEnd, cMax, c, vStart, vStartNew, vEnd, vMax, v, fStart, fStartNew, fEnd, fMax, f, eStart, eStartNew, eEnd, eMax, e, r; 175 PetscErrorCode ierr; 176 177 PetscFunctionBegin; 178 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 179 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 180 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 181 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 182 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 183 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 184 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 185 switch (refiner) { 186 case 0: break; 187 case 1: 188 /* Simplicial 2D */ 189 /* All cells have 3 faces */ 190 for (c = cStart; c < cEnd; ++c) { 191 for (r = 0; r < 4; ++r) { 192 const PetscInt newp = (c - cStart)*4 + r; 193 194 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 195 } 196 } 197 /* Split faces have 2 vertices and the same cells as the parent */ 198 for (f = fStart; f < fEnd; ++f) { 199 for (r = 0; r < 2; ++r) { 200 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 201 PetscInt size; 202 203 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 204 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 205 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 206 } 207 } 208 /* Interior faces have 2 vertices and 2 cells */ 209 for (c = cStart; c < cEnd; ++c) { 210 for (r = 0; r < 3; ++r) { 211 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 212 213 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 214 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 215 } 216 } 217 /* Old vertices have identical supports */ 218 for (v = vStart; v < vEnd; ++v) { 219 const PetscInt newp = vStartNew + (v - vStart); 220 PetscInt size; 221 222 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 223 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 224 } 225 /* Face vertices have 2 + cells*2 supports */ 226 for (f = fStart; f < fEnd; ++f) { 227 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 228 PetscInt size; 229 230 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 231 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr); 232 } 233 break; 234 case 2: 235 /* Hex 2D */ 236 /* All cells have 4 faces */ 237 for (c = cStart; c < cEnd; ++c) { 238 for (r = 0; r < 4; ++r) { 239 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 240 241 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 242 } 243 } 244 /* Split faces have 2 vertices and the same cells as the parent */ 245 for (f = fStart; f < fEnd; ++f) { 246 for (r = 0; r < 2; ++r) { 247 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 248 PetscInt size; 249 250 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 251 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 252 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 253 } 254 } 255 /* Interior faces have 2 vertices and 2 cells */ 256 for (c = cStart; c < cEnd; ++c) { 257 for (r = 0; r < 4; ++r) { 258 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 259 260 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 261 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 262 } 263 } 264 /* Old vertices have identical supports */ 265 for (v = vStart; v < vEnd; ++v) { 266 const PetscInt newp = vStartNew + (v - vStart); 267 PetscInt size; 268 269 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 270 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 271 } 272 /* Face vertices have 2 + cells supports */ 273 for (f = fStart; f < fEnd; ++f) { 274 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 275 PetscInt size; 276 277 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 278 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 279 } 280 /* Cell vertices have 4 supports */ 281 for (c = cStart; c < cEnd; ++c) { 282 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 283 284 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 285 } 286 break; 287 case 3: 288 /* Hybrid Simplicial 2D */ 289 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 290 cMax = PetscMin(cEnd, cMax); 291 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 292 fMax = PetscMin(fEnd, fMax); 293 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 294 /* Interior cells have 3 faces */ 295 for (c = cStart; c < cMax; ++c) { 296 for (r = 0; r < 4; ++r) { 297 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 298 299 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 300 } 301 } 302 /* Hybrid cells have 4 faces */ 303 for (c = cMax; c < cEnd; ++c) { 304 for (r = 0; r < 2; ++r) { 305 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 306 307 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 308 } 309 } 310 /* Interior split faces have 2 vertices and the same cells as the parent */ 311 for (f = fStart; f < fMax; ++f) { 312 for (r = 0; r < 2; ++r) { 313 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 314 PetscInt size; 315 316 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 317 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 318 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 319 } 320 } 321 /* Interior cell faces have 2 vertices and 2 cells */ 322 for (c = cStart; c < cMax; ++c) { 323 for (r = 0; r < 3; ++r) { 324 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 325 326 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 327 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 328 } 329 } 330 /* Hybrid faces have 2 vertices and the same cells */ 331 for (f = fMax; f < fEnd; ++f) { 332 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 333 PetscInt size; 334 335 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 336 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 337 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 338 } 339 /* Hybrid cell faces have 2 vertices and 2 cells */ 340 for (c = cMax; c < cEnd; ++c) { 341 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 342 343 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 344 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 345 } 346 /* Old vertices have identical supports */ 347 for (v = vStart; v < vEnd; ++v) { 348 const PetscInt newp = vStartNew + (v - vStart); 349 PetscInt size; 350 351 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 352 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 353 } 354 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 355 for (f = fStart; f < fMax; ++f) { 356 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 357 const PetscInt *support; 358 PetscInt size, newSize = 2, s; 359 360 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 361 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 362 for (s = 0; s < size; ++s) { 363 if (support[s] >= cMax) newSize += 1; 364 else newSize += 2; 365 } 366 ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr); 367 } 368 break; 369 case 4: 370 /* Hybrid Hex 2D */ 371 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 372 cMax = PetscMin(cEnd, cMax); 373 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 374 fMax = PetscMin(fEnd, fMax); 375 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 376 /* Interior cells have 4 faces */ 377 for (c = cStart; c < cMax; ++c) { 378 for (r = 0; r < 4; ++r) { 379 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 380 381 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 382 } 383 } 384 /* Hybrid cells have 4 faces */ 385 for (c = cMax; c < cEnd; ++c) { 386 for (r = 0; r < 2; ++r) { 387 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 388 389 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 390 } 391 } 392 /* Interior split faces have 2 vertices and the same cells as the parent */ 393 for (f = fStart; f < fMax; ++f) { 394 for (r = 0; r < 2; ++r) { 395 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 396 PetscInt size; 397 398 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 399 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 400 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 401 } 402 } 403 /* Interior cell faces have 2 vertices and 2 cells */ 404 for (c = cStart; c < cMax; ++c) { 405 for (r = 0; r < 4; ++r) { 406 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 407 408 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 409 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 410 } 411 } 412 /* Hybrid faces have 2 vertices and the same cells */ 413 for (f = fMax; f < fEnd; ++f) { 414 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 415 PetscInt size; 416 417 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 418 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 419 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 420 } 421 /* Hybrid cell faces have 2 vertices and 2 cells */ 422 for (c = cMax; c < cEnd; ++c) { 423 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 424 425 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 426 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 427 } 428 /* Old vertices have identical supports */ 429 for (v = vStart; v < vEnd; ++v) { 430 const PetscInt newp = vStartNew + (v - vStart); 431 PetscInt size; 432 433 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 434 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 435 } 436 /* Face vertices have 2 + cells supports */ 437 for (f = fStart; f < fMax; ++f) { 438 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 439 PetscInt size; 440 441 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 442 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 443 } 444 /* Cell vertices have 4 supports */ 445 for (c = cStart; c < cMax; ++c) { 446 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 447 448 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 449 } 450 break; 451 case 5: 452 /* Simplicial 3D */ 453 /* All cells have 4 faces */ 454 for (c = cStart; c < cEnd; ++c) { 455 for (r = 0; r < 8; ++r) { 456 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 457 458 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 459 } 460 } 461 /* Split faces have 3 edges and the same cells as the parent */ 462 for (f = fStart; f < fEnd; ++f) { 463 for (r = 0; r < 4; ++r) { 464 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 465 PetscInt size; 466 467 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 468 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 469 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 470 } 471 } 472 /* Interior cell faces have 3 edges and 2 cells */ 473 for (c = cStart; c < cEnd; ++c) { 474 for (r = 0; r < 8; ++r) { 475 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r; 476 477 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 478 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 479 } 480 } 481 /* Split edges have 2 vertices and the same faces */ 482 for (e = eStart; e < eEnd; ++e) { 483 for (r = 0; r < 2; ++r) { 484 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 485 PetscInt size; 486 487 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 488 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 489 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 490 } 491 } 492 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 493 for (f = fStart; f < fEnd; ++f) { 494 for (r = 0; r < 3; ++r) { 495 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 496 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 497 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 498 499 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 500 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 501 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 502 for (s = 0; s < supportSize; ++s) { 503 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 504 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 505 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 506 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 507 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 508 er = GetTetSomethingInverse_Static(ornt[c], r); 509 if (er == eint[c]) { 510 intFaces += 1; 511 } else { 512 intFaces += 2; 513 } 514 } 515 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 516 } 517 } 518 /* Interior cell edges have 2 vertices and 4 faces */ 519 for (c = cStart; c < cEnd; ++c) { 520 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 521 522 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 523 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 524 } 525 /* Old vertices have identical supports */ 526 for (v = vStart; v < vEnd; ++v) { 527 const PetscInt newp = vStartNew + (v - vStart); 528 PetscInt size; 529 530 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 531 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 532 } 533 /* Edge vertices have 2 + faces*2 + cells*0/1 supports */ 534 for (e = eStart; e < eEnd; ++e) { 535 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 536 PetscInt size, *star = NULL, starSize, s, cellSize = 0; 537 538 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 539 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 540 for (s = 0; s < starSize*2; s += 2) { 541 const PetscInt *cone, *ornt; 542 PetscInt e01, e23; 543 544 if ((star[s] >= cStart) && (star[s] < cEnd)) { 545 /* Check edge 0-1 */ 546 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 547 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 548 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 549 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 550 /* Check edge 2-3 */ 551 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 552 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 553 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 554 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 555 if ((e01 == e) || (e23 == e)) ++cellSize; 556 } 557 } 558 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 559 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr); 560 } 561 break; 562 case 7: 563 /* Hybrid Simplicial 3D */ 564 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart), 565 eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 566 /* Interior cells have 4 faces */ 567 for (c = cStart; c < cMax; ++c) { 568 for (r = 0; r < 8; ++r) { 569 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 570 571 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 572 } 573 } 574 /* Hybrid cells have 5 faces */ 575 for (c = cMax; c < cEnd; ++c) { 576 for (r = 0; r < 4; ++r) { 577 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 578 579 ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr); 580 } 581 } 582 /* Interior split faces have 3 edges and the same cells as the parent */ 583 for (f = fStart; f < fMax; ++f) { 584 for (r = 0; r < 4; ++r) { 585 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 586 PetscInt size; 587 588 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 589 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 590 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 591 } 592 } 593 /* Interior cell faces have 3 edges and 2 cells */ 594 for (c = cStart; c < cMax; ++c) { 595 for (r = 0; r < 8; ++r) { 596 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r; 597 598 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 599 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 600 } 601 } 602 /* Hybrid split faces have 4 edges and the same cells as the parent */ 603 for (f = fMax; f < fEnd; ++f) { 604 for (r = 0; r < 2; ++r) { 605 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 606 PetscInt size; 607 608 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 609 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 610 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 611 } 612 } 613 /* Hybrid cells faces have 4 edges and 2 cells */ 614 for (c = cMax; c < cEnd; ++c) { 615 for (r = 0; r < 3; ++r) { 616 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 617 618 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 619 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 620 } 621 } 622 /* Interior split edges have 2 vertices and the same faces */ 623 for (e = eStart; e < eMax; ++e) { 624 for (r = 0; r < 2; ++r) { 625 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 626 PetscInt size; 627 628 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 629 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 630 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 631 } 632 } 633 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 634 for (f = fStart; f < fMax; ++f) { 635 for (r = 0; r < 3; ++r) { 636 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 637 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 638 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 639 640 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 641 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 642 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 643 for (s = 0; s < supportSize; ++s) { 644 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 645 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 646 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 647 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 648 if (support[s] < cMax) { 649 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 650 er = GetTetSomethingInverse_Static(ornt[c], r); 651 if (er == eint[c]) { 652 intFaces += 1; 653 } else { 654 intFaces += 2; 655 } 656 } else { 657 intFaces += 1; 658 } 659 } 660 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 661 } 662 } 663 /* Interior cell edges have 2 vertices and 4 faces */ 664 for (c = cStart; c < cMax; ++c) { 665 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 666 667 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 668 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 669 } 670 /* Hybrid edges have 2 vertices and the same faces */ 671 for (e = eMax; e < eEnd; ++e) { 672 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 673 PetscInt size; 674 675 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 676 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 677 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 678 } 679 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 680 for (f = fMax; f < fEnd; ++f) { 681 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 682 PetscInt size; 683 684 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 685 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 686 ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr); 687 } 688 /* Interior vertices have identical supports */ 689 for (v = vStart; v < vEnd; ++v) { 690 const PetscInt newp = vStartNew + (v - vStart); 691 PetscInt size; 692 693 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 694 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 695 } 696 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 697 for (e = eStart; e < eMax; ++e) { 698 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 699 const PetscInt *support; 700 PetscInt size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0; 701 702 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 703 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 704 for (s = 0; s < size; ++s) { 705 if (support[s] < fMax) faceSize += 2; 706 else faceSize += 1; 707 } 708 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 709 for (s = 0; s < starSize*2; s += 2) { 710 const PetscInt *cone, *ornt; 711 PetscInt e01, e23; 712 713 if ((star[s] >= cStart) && (star[s] < cMax)) { 714 /* Check edge 0-1 */ 715 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 716 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 717 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 718 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 719 /* Check edge 2-3 */ 720 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 721 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 722 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 723 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 724 if ((e01 == e) || (e23 == e)) ++cellSize; 725 } 726 } 727 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 728 ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr); 729 } 730 break; 731 case 6: 732 /* Hex 3D */ 733 /* All cells have 6 faces */ 734 for (c = cStart; c < cEnd; ++c) { 735 for (r = 0; r < 8; ++r) { 736 const PetscInt newp = (c - cStart)*8 + r; 737 738 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 739 } 740 } 741 /* Split faces have 4 edges and the same cells as the parent */ 742 for (f = fStart; f < fEnd; ++f) { 743 for (r = 0; r < 4; ++r) { 744 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 745 PetscInt size; 746 747 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 748 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 749 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 750 } 751 } 752 /* Interior faces have 4 edges and 2 cells */ 753 for (c = cStart; c < cEnd; ++c) { 754 for (r = 0; r < 12; ++r) { 755 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 756 757 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 758 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 759 } 760 } 761 /* Split edges have 2 vertices and the same faces as the parent */ 762 for (e = eStart; e < eEnd; ++e) { 763 for (r = 0; r < 2; ++r) { 764 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 765 PetscInt size; 766 767 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 768 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 769 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 770 } 771 } 772 /* Face edges have 2 vertices and 2+cells faces */ 773 for (f = fStart; f < fEnd; ++f) { 774 for (r = 0; r < 4; ++r) { 775 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 776 PetscInt size; 777 778 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 779 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 780 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 781 } 782 } 783 /* Cell edges have 2 vertices and 4 faces */ 784 for (c = cStart; c < cEnd; ++c) { 785 for (r = 0; r < 6; ++r) { 786 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 787 788 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 789 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 790 } 791 } 792 /* Old vertices have identical supports */ 793 for (v = vStart; v < vEnd; ++v) { 794 const PetscInt newp = vStartNew + (v - vStart); 795 PetscInt size; 796 797 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 798 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 799 } 800 /* Edge vertices have 2 + faces supports */ 801 for (e = eStart; e < eEnd; ++e) { 802 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 803 PetscInt size; 804 805 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 806 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 807 } 808 /* Face vertices have 4 + cells supports */ 809 for (f = fStart; f < fEnd; ++f) { 810 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 811 PetscInt size; 812 813 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 814 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 815 } 816 /* Cell vertices have 6 supports */ 817 for (c = cStart; c < cEnd; ++c) { 818 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 819 820 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 821 } 822 break; 823 case 8: 824 /* Hybrid Hex 3D */ 825 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart), 826 eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 827 /* Interior cells have 6 faces */ 828 for (c = cStart; c < cMax; ++c) { 829 for (r = 0; r < 8; ++r) { 830 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 831 832 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 833 } 834 } 835 /* Hybrid cells have 6 faces */ 836 for (c = cMax; c < cEnd; ++c) { 837 for (r = 0; r < 4; ++r) { 838 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 839 840 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 841 } 842 } 843 /* Interior split faces have 4 edges and the same cells as the parent */ 844 for (f = fStart; f < fMax; ++f) { 845 for (r = 0; r < 4; ++r) { 846 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 847 PetscInt size; 848 849 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 850 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 851 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 852 } 853 } 854 /* Interior cell faces have 4 edges and 2 cells */ 855 for (c = cStart; c < cMax; ++c) { 856 for (r = 0; r < 12; ++r) { 857 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 858 859 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 860 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 861 } 862 } 863 /* Hybrid split faces have 4 edges and the same cells as the parent */ 864 for (f = fMax; f < fEnd; ++f) { 865 for (r = 0; r < 2; ++r) { 866 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 867 PetscInt size; 868 869 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 870 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 871 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 872 } 873 } 874 /* Hybrid cells faces have 4 edges and 2 cells */ 875 for (c = cMax; c < cEnd; ++c) { 876 for (r = 0; r < 4; ++r) { 877 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r; 878 879 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 880 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 881 } 882 } 883 /* Interior split edges have 2 vertices and the same faces as the parent */ 884 for (e = eStart; e < eMax; ++e) { 885 for (r = 0; r < 2; ++r) { 886 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 887 PetscInt size; 888 889 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 890 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 891 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 892 } 893 } 894 /* Interior face edges have 2 vertices and 2+cells faces */ 895 for (f = fStart; f < fMax; ++f) { 896 for (r = 0; r < 4; ++r) { 897 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 898 PetscInt size; 899 900 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 901 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 902 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 903 } 904 } 905 /* Interior cell edges have 2 vertices and 4 faces */ 906 for (c = cStart; c < cMax; ++c) { 907 for (r = 0; r < 6; ++r) { 908 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 909 910 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 911 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 912 } 913 } 914 /* Hybrid edges have 2 vertices and the same faces */ 915 for (e = eMax; e < eEnd; ++e) { 916 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 917 PetscInt size; 918 919 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 920 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 921 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 922 } 923 /* Hybrid face edges have 2 vertices and 2+cells faces */ 924 for (f = fMax; f < fEnd; ++f) { 925 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 926 PetscInt size; 927 928 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 929 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 930 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 931 } 932 /* Hybrid cell edges have 2 vertices and 4 faces */ 933 for (c = cMax; c < cEnd; ++c) { 934 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 935 936 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 937 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 938 } 939 /* Interior vertices have identical supports */ 940 for (v = vStart; v < vEnd; ++v) { 941 const PetscInt newp = vStartNew + (v - vStart); 942 PetscInt size; 943 944 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 945 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 946 } 947 /* Interior edge vertices have 2 + faces supports */ 948 for (e = eStart; e < eMax; ++e) { 949 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 950 PetscInt size; 951 952 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 953 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 954 } 955 /* Interior face vertices have 4 + cells supports */ 956 for (f = fStart; f < fMax; ++f) { 957 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 958 PetscInt size; 959 960 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 961 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 962 } 963 /* Interior cell vertices have 6 supports */ 964 for (c = cStart; c < cMax; ++c) { 965 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 966 967 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 968 } 969 break; 970 default: 971 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 972 } 973 PetscFunctionReturn(0); 974 } 975 976 #undef __FUNCT__ 977 #define __FUNCT__ "CellRefinerSetCones" 978 static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 979 { 980 const PetscInt *faces, cellInd[4] = {0, 1, 2, 3}; 981 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 982 PetscInt cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew, fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew; 983 PetscInt depth, maxSupportSize, *supportRef, c, f, e, v, r, p; 984 PetscErrorCode ierr; 985 986 PetscFunctionBegin; 987 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 988 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 989 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 990 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 991 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 992 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 993 if (refiner) { 994 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 995 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 996 } 997 switch (refiner) { 998 case 0: break; 999 case 1: 1000 /* Simplicial 2D */ 1001 /* 1002 2 1003 |\ 1004 | \ 1005 | \ 1006 | \ 1007 | C \ 1008 | \ 1009 | \ 1010 2---1---1 1011 |\ D / \ 1012 | 2 0 \ 1013 |A \ / B \ 1014 0---0-------1 1015 */ 1016 /* All cells have 3 faces */ 1017 for (c = cStart; c < cEnd; ++c) { 1018 const PetscInt newp = cStartNew + (c - cStart)*4; 1019 const PetscInt *cone, *ornt; 1020 PetscInt coneNew[3], orntNew[3]; 1021 1022 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1023 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1024 /* A triangle */ 1025 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1026 orntNew[0] = ornt[0]; 1027 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1028 orntNew[1] = -2; 1029 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1030 orntNew[2] = ornt[2]; 1031 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1032 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1033 #if 1 1034 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); 1035 for (p = 0; p < 3; ++p) { 1036 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); 1037 } 1038 #endif 1039 /* B triangle */ 1040 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1041 orntNew[0] = ornt[0]; 1042 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1043 orntNew[1] = ornt[1]; 1044 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1045 orntNew[2] = -2; 1046 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1047 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1048 #if 1 1049 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); 1050 for (p = 0; p < 3; ++p) { 1051 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); 1052 } 1053 #endif 1054 /* C triangle */ 1055 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1056 orntNew[0] = -2; 1057 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1058 orntNew[1] = ornt[1]; 1059 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1060 orntNew[2] = ornt[2]; 1061 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1062 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1063 #if 1 1064 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); 1065 for (p = 0; p < 3; ++p) { 1066 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); 1067 } 1068 #endif 1069 /* D triangle */ 1070 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1071 orntNew[0] = 0; 1072 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1073 orntNew[1] = 0; 1074 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1075 orntNew[2] = 0; 1076 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1077 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1078 #if 1 1079 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); 1080 for (p = 0; p < 3; ++p) { 1081 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); 1082 } 1083 #endif 1084 } 1085 /* Split faces have 2 vertices and the same cells as the parent */ 1086 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1087 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 1088 for (f = fStart; f < fEnd; ++f) { 1089 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1090 1091 for (r = 0; r < 2; ++r) { 1092 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1093 const PetscInt *cone, *ornt, *support; 1094 PetscInt coneNew[2], coneSize, c, supportSize, s; 1095 1096 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1097 coneNew[0] = vStartNew + (cone[0] - vStart); 1098 coneNew[1] = vStartNew + (cone[1] - vStart); 1099 coneNew[(r+1)%2] = newv; 1100 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1101 #if 1 1102 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1103 for (p = 0; p < 2; ++p) { 1104 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); 1105 } 1106 #endif 1107 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1108 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1109 for (s = 0; s < supportSize; ++s) { 1110 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1111 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1112 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1113 for (c = 0; c < coneSize; ++c) { 1114 if (cone[c] == f) break; 1115 } 1116 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1117 } 1118 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1119 #if 1 1120 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1121 for (p = 0; p < supportSize; ++p) { 1122 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); 1123 } 1124 #endif 1125 } 1126 } 1127 /* Interior faces have 2 vertices and 2 cells */ 1128 for (c = cStart; c < cEnd; ++c) { 1129 const PetscInt *cone; 1130 1131 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1132 for (r = 0; r < 3; ++r) { 1133 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 1134 PetscInt coneNew[2]; 1135 PetscInt supportNew[2]; 1136 1137 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1138 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1139 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1140 #if 1 1141 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1142 for (p = 0; p < 2; ++p) { 1143 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); 1144 } 1145 #endif 1146 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1147 supportNew[1] = (c - cStart)*4 + 3; 1148 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1149 #if 1 1150 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1151 for (p = 0; p < 2; ++p) { 1152 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); 1153 } 1154 #endif 1155 } 1156 } 1157 /* Old vertices have identical supports */ 1158 for (v = vStart; v < vEnd; ++v) { 1159 const PetscInt newp = vStartNew + (v - vStart); 1160 const PetscInt *support, *cone; 1161 PetscInt size, s; 1162 1163 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1164 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1165 for (s = 0; s < size; ++s) { 1166 PetscInt r = 0; 1167 1168 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1169 if (cone[1] == v) r = 1; 1170 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1171 } 1172 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1173 #if 1 1174 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1175 for (p = 0; p < size; ++p) { 1176 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); 1177 } 1178 #endif 1179 } 1180 /* Face vertices have 2 + cells*2 supports */ 1181 for (f = fStart; f < fEnd; ++f) { 1182 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1183 const PetscInt *cone, *support; 1184 PetscInt size, s; 1185 1186 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1187 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1188 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1189 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1190 for (s = 0; s < size; ++s) { 1191 PetscInt r = 0; 1192 1193 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1194 if (cone[1] == f) r = 1; 1195 else if (cone[2] == f) r = 2; 1196 supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1197 supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 1198 } 1199 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1200 #if 1 1201 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1202 for (p = 0; p < 2+size*2; ++p) { 1203 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); 1204 } 1205 #endif 1206 } 1207 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1208 break; 1209 case 2: 1210 /* Hex 2D */ 1211 /* 1212 3---------2---------2 1213 | | | 1214 | D 2 C | 1215 | | | 1216 3----3----0----1----1 1217 | | | 1218 | A 0 B | 1219 | | | 1220 0---------0---------1 1221 */ 1222 /* All cells have 4 faces */ 1223 for (c = cStart; c < cEnd; ++c) { 1224 const PetscInt newp = (c - cStart)*4; 1225 const PetscInt *cone, *ornt; 1226 PetscInt coneNew[4], orntNew[4]; 1227 1228 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1229 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1230 /* A quad */ 1231 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1232 orntNew[0] = ornt[0]; 1233 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1234 orntNew[1] = 0; 1235 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1236 orntNew[2] = -2; 1237 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 1238 orntNew[3] = ornt[3]; 1239 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1240 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1241 #if 1 1242 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); 1243 for (p = 0; p < 4; ++p) { 1244 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1245 } 1246 #endif 1247 /* B quad */ 1248 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1249 orntNew[0] = ornt[0]; 1250 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1251 orntNew[1] = ornt[1]; 1252 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1253 orntNew[2] = 0; 1254 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1255 orntNew[3] = -2; 1256 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1257 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1258 #if 1 1259 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); 1260 for (p = 0; p < 4; ++p) { 1261 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); 1262 } 1263 #endif 1264 /* C quad */ 1265 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1266 orntNew[0] = -2; 1267 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1268 orntNew[1] = ornt[1]; 1269 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1270 orntNew[2] = ornt[2]; 1271 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1272 orntNew[3] = 0; 1273 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1274 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1275 #if 1 1276 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); 1277 for (p = 0; p < 4; ++p) { 1278 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); 1279 } 1280 #endif 1281 /* D quad */ 1282 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1283 orntNew[0] = 0; 1284 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1285 orntNew[1] = -2; 1286 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1287 orntNew[2] = ornt[2]; 1288 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 1289 orntNew[3] = ornt[3]; 1290 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1291 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1292 #if 1 1293 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); 1294 for (p = 0; p < 4; ++p) { 1295 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); 1296 } 1297 #endif 1298 } 1299 /* Split faces have 2 vertices and the same cells as the parent */ 1300 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1301 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 1302 for (f = fStart; f < fEnd; ++f) { 1303 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1304 1305 for (r = 0; r < 2; ++r) { 1306 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1307 const PetscInt *cone, *ornt, *support; 1308 PetscInt coneNew[2], coneSize, c, supportSize, s; 1309 1310 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1311 coneNew[0] = vStartNew + (cone[0] - vStart); 1312 coneNew[1] = vStartNew + (cone[1] - vStart); 1313 coneNew[(r+1)%2] = newv; 1314 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1315 #if 1 1316 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1317 for (p = 0; p < 2; ++p) { 1318 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); 1319 } 1320 #endif 1321 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1322 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1323 for (s = 0; s < supportSize; ++s) { 1324 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1325 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1326 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1327 for (c = 0; c < coneSize; ++c) { 1328 if (cone[c] == f) break; 1329 } 1330 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 1331 } 1332 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1333 #if 1 1334 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1335 for (p = 0; p < supportSize; ++p) { 1336 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); 1337 } 1338 #endif 1339 } 1340 } 1341 /* Interior faces have 2 vertices and 2 cells */ 1342 for (c = cStart; c < cEnd; ++c) { 1343 const PetscInt *cone; 1344 PetscInt coneNew[2], supportNew[2]; 1345 1346 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1347 for (r = 0; r < 4; ++r) { 1348 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 1349 1350 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1351 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1352 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1353 #if 1 1354 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1355 for (p = 0; p < 2; ++p) { 1356 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); 1357 } 1358 #endif 1359 supportNew[0] = (c - cStart)*4 + r; 1360 supportNew[1] = (c - cStart)*4 + (r+1)%4; 1361 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1362 #if 1 1363 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1364 for (p = 0; p < 2; ++p) { 1365 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); 1366 } 1367 #endif 1368 } 1369 } 1370 /* Old vertices have identical supports */ 1371 for (v = vStart; v < vEnd; ++v) { 1372 const PetscInt newp = vStartNew + (v - vStart); 1373 const PetscInt *support, *cone; 1374 PetscInt size, s; 1375 1376 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1377 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1378 for (s = 0; s < size; ++s) { 1379 PetscInt r = 0; 1380 1381 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1382 if (cone[1] == v) r = 1; 1383 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1384 } 1385 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1386 #if 1 1387 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1388 for (p = 0; p < size; ++p) { 1389 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); 1390 } 1391 #endif 1392 } 1393 /* Face vertices have 2 + cells supports */ 1394 for (f = fStart; f < fEnd; ++f) { 1395 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1396 const PetscInt *cone, *support; 1397 PetscInt size, s; 1398 1399 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1400 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1401 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1402 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1403 for (s = 0; s < size; ++s) { 1404 PetscInt r = 0; 1405 1406 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1407 if (cone[1] == f) r = 1; 1408 else if (cone[2] == f) r = 2; 1409 else if (cone[3] == f) r = 3; 1410 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r; 1411 } 1412 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1413 #if 1 1414 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1415 for (p = 0; p < 2+size; ++p) { 1416 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); 1417 } 1418 #endif 1419 } 1420 /* Cell vertices have 4 supports */ 1421 for (c = cStart; c < cEnd; ++c) { 1422 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1423 PetscInt supportNew[4]; 1424 1425 for (r = 0; r < 4; ++r) { 1426 supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 1427 } 1428 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1429 } 1430 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1431 break; 1432 case 3: 1433 /* Hybrid Simplicial 2D */ 1434 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1435 cMax = PetscMin(cEnd, cMax); 1436 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1437 fMax = PetscMin(fEnd, fMax); 1438 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 1439 /* Interior cells have 3 faces */ 1440 for (c = cStart; c < cMax; ++c) { 1441 const PetscInt newp = cStartNew + (c - cStart)*4; 1442 const PetscInt *cone, *ornt; 1443 PetscInt coneNew[3], orntNew[3]; 1444 1445 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1446 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1447 /* A triangle */ 1448 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1449 orntNew[0] = ornt[0]; 1450 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 1451 orntNew[1] = -2; 1452 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1453 orntNew[2] = ornt[2]; 1454 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1455 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1456 #if 1 1457 if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+0, cStartNew, cMaxNew); 1458 for (p = 0; p < 3; ++p) { 1459 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 1460 } 1461 #endif 1462 /* B triangle */ 1463 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1464 orntNew[0] = ornt[0]; 1465 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1466 orntNew[1] = ornt[1]; 1467 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 1468 orntNew[2] = -2; 1469 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1470 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1471 #if 1 1472 if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+1, cStartNew, cMaxNew); 1473 for (p = 0; p < 3; ++p) { 1474 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 1475 } 1476 #endif 1477 /* C triangle */ 1478 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 1479 orntNew[0] = -2; 1480 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1481 orntNew[1] = ornt[1]; 1482 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1483 orntNew[2] = ornt[2]; 1484 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1485 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1486 #if 1 1487 if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+2, cStartNew, cMaxNew); 1488 for (p = 0; p < 3; ++p) { 1489 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 1490 } 1491 #endif 1492 /* D triangle */ 1493 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 1494 orntNew[0] = 0; 1495 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 1496 orntNew[1] = 0; 1497 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 1498 orntNew[2] = 0; 1499 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1500 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1501 #if 1 1502 if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+3, cStartNew, cMaxNew); 1503 for (p = 0; p < 3; ++p) { 1504 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 1505 } 1506 #endif 1507 } 1508 /* 1509 2----3----3 1510 | | 1511 | B | 1512 | | 1513 0----4--- 1 1514 | | 1515 | A | 1516 | | 1517 0----2----1 1518 */ 1519 /* Hybrid cells have 4 faces */ 1520 for (c = cMax; c < cEnd; ++c) { 1521 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 1522 const PetscInt *cone, *ornt; 1523 PetscInt coneNew[4], orntNew[4], r; 1524 1525 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1526 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1527 r = (ornt[0] < 0 ? 1 : 0); 1528 /* A quad */ 1529 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + r; 1530 orntNew[0] = ornt[0]; 1531 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + r; 1532 orntNew[1] = ornt[1]; 1533 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax); 1534 orntNew[2+r] = 0; 1535 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1536 orntNew[3-r] = 0; 1537 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1538 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1539 #if 1 1540 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); 1541 for (p = 0; p < 4; ++p) { 1542 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); 1543 } 1544 #endif 1545 /* B quad */ 1546 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + 1-r; 1547 orntNew[0] = ornt[0]; 1548 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + 1-r; 1549 orntNew[1] = ornt[1]; 1550 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1551 orntNew[2+r] = 0; 1552 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax); 1553 orntNew[3-r] = 0; 1554 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1555 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1556 #if 1 1557 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); 1558 for (p = 0; p < 4; ++p) { 1559 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); 1560 } 1561 #endif 1562 } 1563 /* Interior split faces have 2 vertices and the same cells as the parent */ 1564 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1565 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 1566 for (f = fStart; f < fMax; ++f) { 1567 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1568 1569 for (r = 0; r < 2; ++r) { 1570 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1571 const PetscInt *cone, *ornt, *support; 1572 PetscInt coneNew[2], coneSize, c, supportSize, s; 1573 1574 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1575 coneNew[0] = vStartNew + (cone[0] - vStart); 1576 coneNew[1] = vStartNew + (cone[1] - vStart); 1577 coneNew[(r+1)%2] = newv; 1578 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1579 #if 1 1580 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1581 for (p = 0; p < 2; ++p) { 1582 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); 1583 } 1584 #endif 1585 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1586 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1587 for (s = 0; s < supportSize; ++s) { 1588 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1589 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1590 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1591 for (c = 0; c < coneSize; ++c) if (cone[c] == f) break; 1592 if (support[s] >= cMax) { 1593 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r); 1594 } else { 1595 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1596 } 1597 } 1598 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1599 #if 1 1600 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1601 for (p = 0; p < supportSize; ++p) { 1602 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); 1603 } 1604 #endif 1605 } 1606 } 1607 /* Interior cell faces have 2 vertices and 2 cells */ 1608 for (c = cStart; c < cMax; ++c) { 1609 const PetscInt *cone; 1610 1611 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1612 for (r = 0; r < 3; ++r) { 1613 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 1614 PetscInt coneNew[2]; 1615 PetscInt supportNew[2]; 1616 1617 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1618 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1619 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1620 #if 1 1621 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1622 for (p = 0; p < 2; ++p) { 1623 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); 1624 } 1625 #endif 1626 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1627 supportNew[1] = (c - cStart)*4 + 3; 1628 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1629 #if 1 1630 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1631 for (p = 0; p < 2; ++p) { 1632 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); 1633 } 1634 #endif 1635 } 1636 } 1637 /* Interior hybrid faces have 2 vertices and the same cells */ 1638 for (f = fMax; f < fEnd; ++f) { 1639 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 1640 const PetscInt *cone, *ornt; 1641 const PetscInt *support; 1642 PetscInt coneNew[2]; 1643 PetscInt supportNew[2]; 1644 PetscInt size, s, r; 1645 1646 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1647 coneNew[0] = vStartNew + (cone[0] - vStart); 1648 coneNew[1] = vStartNew + (cone[1] - vStart); 1649 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1650 #if 1 1651 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1652 for (p = 0; p < 2; ++p) { 1653 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); 1654 } 1655 #endif 1656 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1657 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1658 for (s = 0; s < size; ++s) { 1659 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1660 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1661 for (r = 0; r < 2; ++r) { 1662 if (cone[r+2] == f) break; 1663 } 1664 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r); 1665 } 1666 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1667 #if 1 1668 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1669 for (p = 0; p < size; ++p) { 1670 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); 1671 } 1672 #endif 1673 } 1674 /* Cell hybrid faces have 2 vertices and 2 cells */ 1675 for (c = cMax; c < cEnd; ++c) { 1676 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1677 const PetscInt *cone; 1678 PetscInt coneNew[2]; 1679 PetscInt supportNew[2]; 1680 1681 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1682 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 1683 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 1684 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1685 #if 1 1686 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1687 for (p = 0; p < 2; ++p) { 1688 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); 1689 } 1690 #endif 1691 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 1692 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 1693 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1694 #if 1 1695 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1696 for (p = 0; p < 2; ++p) { 1697 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); 1698 } 1699 #endif 1700 } 1701 /* Old vertices have identical supports */ 1702 for (v = vStart; v < vEnd; ++v) { 1703 const PetscInt newp = vStartNew + (v - vStart); 1704 const PetscInt *support, *cone; 1705 PetscInt size, s; 1706 1707 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1708 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1709 for (s = 0; s < size; ++s) { 1710 if (support[s] >= fMax) { 1711 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax); 1712 } else { 1713 PetscInt r = 0; 1714 1715 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1716 if (cone[1] == v) r = 1; 1717 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1718 } 1719 } 1720 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1721 #if 1 1722 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1723 for (p = 0; p < size; ++p) { 1724 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); 1725 } 1726 #endif 1727 } 1728 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 1729 for (f = fStart; f < fMax; ++f) { 1730 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1731 const PetscInt *cone, *support; 1732 PetscInt size, newSize = 2, s; 1733 1734 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1735 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1736 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1737 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1738 for (s = 0; s < size; ++s) { 1739 PetscInt r = 0; 1740 1741 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1742 if (support[s] >= cMax) { 1743 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax); 1744 1745 newSize += 1; 1746 } else { 1747 if (cone[1] == f) r = 1; 1748 else if (cone[2] == f) r = 2; 1749 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1750 supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r; 1751 1752 newSize += 2; 1753 } 1754 } 1755 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1756 #if 1 1757 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1758 for (p = 0; p < newSize; ++p) { 1759 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); 1760 } 1761 #endif 1762 } 1763 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1764 break; 1765 case 4: 1766 /* Hybrid Hex 2D */ 1767 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1768 cMax = PetscMin(cEnd, cMax); 1769 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1770 fMax = PetscMin(fEnd, fMax); 1771 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 1772 /* Interior cells have 4 faces */ 1773 for (c = cStart; c < cMax; ++c) { 1774 const PetscInt newp = cStartNew + (c - cStart)*4; 1775 const PetscInt *cone, *ornt; 1776 PetscInt coneNew[4], orntNew[4]; 1777 1778 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1779 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1780 /* A quad */ 1781 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1782 orntNew[0] = ornt[0]; 1783 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 1784 orntNew[1] = 0; 1785 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 1786 orntNew[2] = -2; 1787 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 1788 orntNew[3] = ornt[3]; 1789 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1790 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1791 #if 1 1792 if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+0, cStartNew, cMaxNew); 1793 for (p = 0; p < 4; ++p) { 1794 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 1795 } 1796 #endif 1797 /* B quad */ 1798 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1799 orntNew[0] = ornt[0]; 1800 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1801 orntNew[1] = ornt[1]; 1802 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 1803 orntNew[2] = 0; 1804 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 1805 orntNew[3] = -2; 1806 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1807 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1808 #if 1 1809 if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+1, cStartNew, cMaxNew); 1810 for (p = 0; p < 4; ++p) { 1811 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 1812 } 1813 #endif 1814 /* C quad */ 1815 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 1816 orntNew[0] = -2; 1817 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1818 orntNew[1] = ornt[1]; 1819 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1820 orntNew[2] = ornt[2]; 1821 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 1822 orntNew[3] = 0; 1823 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1824 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1825 #if 1 1826 if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+2, cStartNew, cMaxNew); 1827 for (p = 0; p < 4; ++p) { 1828 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 1829 } 1830 #endif 1831 /* D quad */ 1832 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 1833 orntNew[0] = 0; 1834 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 1835 orntNew[1] = -2; 1836 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1837 orntNew[2] = ornt[2]; 1838 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 1839 orntNew[3] = ornt[3]; 1840 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1841 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1842 #if 1 1843 if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+3, cStartNew, cMaxNew); 1844 for (p = 0; p < 4; ++p) { 1845 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 1846 } 1847 #endif 1848 } 1849 /* 1850 2----3----3 1851 | | 1852 | B | 1853 | | 1854 0----4--- 1 1855 | | 1856 | A | 1857 | | 1858 0----2----1 1859 */ 1860 /* Hybrid cells have 4 faces */ 1861 for (c = cMax; c < cEnd; ++c) { 1862 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 1863 const PetscInt *cone, *ornt; 1864 PetscInt coneNew[4], orntNew[4]; 1865 1866 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1867 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1868 /* A quad */ 1869 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1870 orntNew[0] = ornt[0]; 1871 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1872 orntNew[1] = ornt[1]; 1873 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax); 1874 orntNew[2] = 0; 1875 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 1876 orntNew[3] = 0; 1877 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1878 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1879 #if 1 1880 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); 1881 for (p = 0; p < 4; ++p) { 1882 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); 1883 } 1884 #endif 1885 /* B quad */ 1886 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1887 orntNew[0] = ornt[0]; 1888 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1889 orntNew[1] = ornt[1]; 1890 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 1891 orntNew[2] = 0; 1892 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax); 1893 orntNew[3] = 0; 1894 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1895 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1896 #if 1 1897 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); 1898 for (p = 0; p < 4; ++p) { 1899 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); 1900 } 1901 #endif 1902 } 1903 /* Interior split faces have 2 vertices and the same cells as the parent */ 1904 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1905 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 1906 for (f = fStart; f < fMax; ++f) { 1907 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1908 1909 for (r = 0; r < 2; ++r) { 1910 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1911 const PetscInt *cone, *ornt, *support; 1912 PetscInt coneNew[2], coneSize, c, supportSize, s; 1913 1914 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1915 coneNew[0] = vStartNew + (cone[0] - vStart); 1916 coneNew[1] = vStartNew + (cone[1] - vStart); 1917 coneNew[(r+1)%2] = newv; 1918 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1919 #if 1 1920 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1921 for (p = 0; p < 2; ++p) { 1922 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); 1923 } 1924 #endif 1925 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1926 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1927 for (s = 0; s < supportSize; ++s) { 1928 if (support[s] >= cMax) { 1929 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 1930 } else { 1931 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1932 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1933 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1934 for (c = 0; c < coneSize; ++c) { 1935 if (cone[c] == f) break; 1936 } 1937 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 1938 } 1939 } 1940 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1941 #if 1 1942 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1943 for (p = 0; p < supportSize; ++p) { 1944 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); 1945 } 1946 #endif 1947 } 1948 } 1949 /* Interior cell faces have 2 vertices and 2 cells */ 1950 for (c = cStart; c < cMax; ++c) { 1951 const PetscInt *cone; 1952 1953 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1954 for (r = 0; r < 4; ++r) { 1955 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 1956 PetscInt coneNew[2], supportNew[2]; 1957 1958 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1959 coneNew[1] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 1960 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1961 #if 1 1962 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1963 for (p = 0; p < 2; ++p) { 1964 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 1965 } 1966 #endif 1967 supportNew[0] = (c - cStart)*4 + r; 1968 supportNew[1] = (c - cStart)*4 + (r+1)%4; 1969 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1970 #if 1 1971 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1972 for (p = 0; p < 2; ++p) { 1973 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); 1974 } 1975 #endif 1976 } 1977 } 1978 /* Hybrid faces have 2 vertices and the same cells */ 1979 for (f = fMax; f < fEnd; ++f) { 1980 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 1981 const PetscInt *cone, *support; 1982 PetscInt coneNew[2], supportNew[2]; 1983 PetscInt size, s, r; 1984 1985 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1986 coneNew[0] = vStartNew + (cone[0] - vStart); 1987 coneNew[1] = vStartNew + (cone[1] - vStart); 1988 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1989 #if 1 1990 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1991 for (p = 0; p < 2; ++p) { 1992 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); 1993 } 1994 #endif 1995 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1996 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1997 for (s = 0; s < size; ++s) { 1998 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1999 for (r = 0; r < 2; ++r) { 2000 if (cone[r+2] == f) break; 2001 } 2002 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 2003 } 2004 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2005 #if 1 2006 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2007 for (p = 0; p < size; ++p) { 2008 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); 2009 } 2010 #endif 2011 } 2012 /* Cell hybrid faces have 2 vertices and 2 cells */ 2013 for (c = cMax; c < cEnd; ++c) { 2014 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2015 const PetscInt *cone; 2016 PetscInt coneNew[2], supportNew[2]; 2017 2018 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2019 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 2020 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 2021 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2022 #if 1 2023 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2024 for (p = 0; p < 2; ++p) { 2025 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); 2026 } 2027 #endif 2028 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 2029 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 2030 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2031 #if 1 2032 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2033 for (p = 0; p < 2; ++p) { 2034 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); 2035 } 2036 #endif 2037 } 2038 /* Old vertices have identical supports */ 2039 for (v = vStart; v < vEnd; ++v) { 2040 const PetscInt newp = vStartNew + (v - vStart); 2041 const PetscInt *support, *cone; 2042 PetscInt size, s; 2043 2044 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2045 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2046 for (s = 0; s < size; ++s) { 2047 if (support[s] >= fMax) { 2048 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax); 2049 } else { 2050 PetscInt r = 0; 2051 2052 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2053 if (cone[1] == v) r = 1; 2054 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2055 } 2056 } 2057 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2058 #if 1 2059 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2060 for (p = 0; p < size; ++p) { 2061 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); 2062 } 2063 #endif 2064 } 2065 /* Face vertices have 2 + cells supports */ 2066 for (f = fStart; f < fMax; ++f) { 2067 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2068 const PetscInt *cone, *support; 2069 PetscInt size, s; 2070 2071 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2072 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2073 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2074 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2075 for (s = 0; s < size; ++s) { 2076 PetscInt r = 0; 2077 2078 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2079 if (support[s] >= cMax) { 2080 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax); 2081 } else { 2082 if (cone[1] == f) r = 1; 2083 else if (cone[2] == f) r = 2; 2084 else if (cone[3] == f) r = 3; 2085 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r; 2086 } 2087 } 2088 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2089 #if 1 2090 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2091 for (p = 0; p < 2+size; ++p) { 2092 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); 2093 } 2094 #endif 2095 } 2096 /* Cell vertices have 4 supports */ 2097 for (c = cStart; c < cMax; ++c) { 2098 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 2099 PetscInt supportNew[4]; 2100 2101 for (r = 0; r < 4; ++r) { 2102 supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 2103 } 2104 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2105 } 2106 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2107 break; 2108 case 5: 2109 /* Simplicial 3D */ 2110 /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 2111 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 2112 for (c = cStart; c < cEnd; ++c) { 2113 const PetscInt newp = cStartNew + (c - cStart)*8; 2114 const PetscInt *cone, *ornt; 2115 PetscInt coneNew[4], orntNew[4]; 2116 2117 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2118 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2119 /* A tetrahedron: {0, a, c, d} */ 2120 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 2121 orntNew[0] = ornt[0]; 2122 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 2123 orntNew[1] = ornt[1]; 2124 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 2125 orntNew[2] = ornt[2]; 2126 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 2127 orntNew[3] = 0; 2128 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2129 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2130 #if 1 2131 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); 2132 for (p = 0; p < 4; ++p) { 2133 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); 2134 } 2135 #endif 2136 /* B tetrahedron: {a, 1, b, e} */ 2137 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 2138 orntNew[0] = ornt[0]; 2139 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 2140 orntNew[1] = ornt[1]; 2141 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2142 orntNew[2] = 0; 2143 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 2144 orntNew[3] = ornt[3]; 2145 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2146 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2147 #if 1 2148 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); 2149 for (p = 0; p < 4; ++p) { 2150 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); 2151 } 2152 #endif 2153 /* C tetrahedron: {c, b, 2, f} */ 2154 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 2155 orntNew[0] = ornt[0]; 2156 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2157 orntNew[1] = 0; 2158 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 2159 orntNew[2] = ornt[2]; 2160 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 2161 orntNew[3] = ornt[3]; 2162 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2163 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2164 #if 1 2165 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); 2166 for (p = 0; p < 4; ++p) { 2167 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); 2168 } 2169 #endif 2170 /* D tetrahedron: {d, e, f, 3} */ 2171 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2172 orntNew[0] = 0; 2173 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 2174 orntNew[1] = ornt[1]; 2175 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 2176 orntNew[2] = ornt[2]; 2177 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 2178 orntNew[3] = ornt[3]; 2179 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2180 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2181 #if 1 2182 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); 2183 for (p = 0; p < 4; ++p) { 2184 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); 2185 } 2186 #endif 2187 /* A' tetrahedron: {d, a, c, f} */ 2188 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 2189 orntNew[0] = -3; 2190 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 2191 orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0); 2192 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2193 orntNew[2] = 0; 2194 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2195 orntNew[3] = 2; 2196 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 2197 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 2198 #if 1 2199 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); 2200 for (p = 0; p < 4; ++p) { 2201 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); 2202 } 2203 #endif 2204 /* B' tetrahedron: {e, b, a, f} */ 2205 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2206 orntNew[0] = -3; 2207 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2208 orntNew[1] = 1; 2209 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2210 orntNew[2] = 0; 2211 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 2212 orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0); 2213 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 2214 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 2215 #if 1 2216 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); 2217 for (p = 0; p < 4; ++p) { 2218 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); 2219 } 2220 #endif 2221 /* C' tetrahedron: {b, f, c, a} */ 2222 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2223 orntNew[0] = -3; 2224 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 2225 orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2); 2226 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2227 orntNew[2] = -3; 2228 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2229 orntNew[3] = -2; 2230 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 2231 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 2232 #if 1 2233 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); 2234 for (p = 0; p < 4; ++p) { 2235 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); 2236 } 2237 #endif 2238 /* D' tetrahedron: {f, e, d, a} */ 2239 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2240 orntNew[0] = -3; 2241 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2242 orntNew[1] = -3; 2243 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 2244 orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0); 2245 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2246 orntNew[3] = -3; 2247 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 2248 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 2249 #if 1 2250 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); 2251 for (p = 0; p < 4; ++p) { 2252 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); 2253 } 2254 #endif 2255 } 2256 /* Split faces have 3 edges and the same cells as the parent */ 2257 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2258 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 2259 for (f = fStart; f < fEnd; ++f) { 2260 const PetscInt newp = fStartNew + (f - fStart)*4; 2261 const PetscInt *cone, *ornt, *support; 2262 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 2263 2264 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2265 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2266 /* A triangle */ 2267 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 2268 orntNew[0] = ornt[0]; 2269 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2270 orntNew[1] = -2; 2271 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 2272 orntNew[2] = ornt[2]; 2273 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2274 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2275 #if 1 2276 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); 2277 for (p = 0; p < 3; ++p) { 2278 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); 2279 } 2280 #endif 2281 /* B triangle */ 2282 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 2283 orntNew[0] = ornt[0]; 2284 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 2285 orntNew[1] = ornt[1]; 2286 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2287 orntNew[2] = -2; 2288 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2289 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2290 #if 1 2291 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); 2292 for (p = 0; p < 3; ++p) { 2293 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); 2294 } 2295 #endif 2296 /* C triangle */ 2297 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2298 orntNew[0] = -2; 2299 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 2300 orntNew[1] = ornt[1]; 2301 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 2302 orntNew[2] = ornt[2]; 2303 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2304 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2305 #if 1 2306 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); 2307 for (p = 0; p < 3; ++p) { 2308 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); 2309 } 2310 #endif 2311 /* D triangle */ 2312 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2313 orntNew[0] = 0; 2314 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2315 orntNew[1] = 0; 2316 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2317 orntNew[2] = 0; 2318 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2319 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2320 #if 1 2321 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); 2322 for (p = 0; p < 3; ++p) { 2323 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); 2324 } 2325 #endif 2326 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2327 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2328 for (r = 0; r < 4; ++r) { 2329 for (s = 0; s < supportSize; ++s) { 2330 PetscInt subf; 2331 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2332 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2333 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2334 for (c = 0; c < coneSize; ++c) { 2335 if (cone[c] == f) break; 2336 } 2337 subf = GetTriSubfaceInverse_Static(ornt[c], r); 2338 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 2339 } 2340 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 2341 #if 1 2342 if ((newp+r < fStartNew) || (newp+r >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+r, fStartNew, fEndNew); 2343 for (p = 0; p < supportSize; ++p) { 2344 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); 2345 } 2346 #endif 2347 } 2348 } 2349 /* Interior faces have 3 edges and 2 cells */ 2350 for (c = cStart; c < cEnd; ++c) { 2351 PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 2352 const PetscInt *cone, *ornt; 2353 PetscInt coneNew[3], orntNew[3]; 2354 PetscInt supportNew[2]; 2355 2356 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2357 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2358 /* Face A: {c, a, d} */ 2359 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 2360 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2361 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 2362 orntNew[1] = ornt[1] < 0 ? -2 : 0; 2363 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2); 2364 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2365 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2366 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2367 #if 1 2368 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2369 for (p = 0; p < 3; ++p) { 2370 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); 2371 } 2372 #endif 2373 supportNew[0] = (c - cStart)*8 + 0; 2374 supportNew[1] = (c - cStart)*8 + 0+4; 2375 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2376 #if 1 2377 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2378 for (p = 0; p < 2; ++p) { 2379 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); 2380 } 2381 #endif 2382 ++newp; 2383 /* Face B: {a, b, e} */ 2384 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 2385 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2386 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0); 2387 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2388 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 2389 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2390 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2391 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2392 #if 1 2393 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2394 for (p = 0; p < 3; ++p) { 2395 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); 2396 } 2397 #endif 2398 supportNew[0] = (c - cStart)*8 + 1; 2399 supportNew[1] = (c - cStart)*8 + 1+4; 2400 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2401 #if 1 2402 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2403 for (p = 0; p < 2; ++p) { 2404 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); 2405 } 2406 #endif 2407 ++newp; 2408 /* Face C: {c, f, b} */ 2409 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 2410 orntNew[0] = ornt[2] < 0 ? -2 : 0; 2411 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 2412 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2413 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1); 2414 orntNew[2] = ornt[0] < 0 ? -2 : 0; 2415 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2416 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2417 #if 1 2418 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2419 for (p = 0; p < 3; ++p) { 2420 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); 2421 } 2422 #endif 2423 supportNew[0] = (c - cStart)*8 + 2; 2424 supportNew[1] = (c - cStart)*8 + 2+4; 2425 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2426 #if 1 2427 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2428 for (p = 0; p < 2; ++p) { 2429 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); 2430 } 2431 #endif 2432 ++newp; 2433 /* Face D: {d, e, f} */ 2434 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0); 2435 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2436 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 2437 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2438 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 2439 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2440 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2441 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2442 #if 1 2443 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2444 for (p = 0; p < 3; ++p) { 2445 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); 2446 } 2447 #endif 2448 supportNew[0] = (c - cStart)*8 + 3; 2449 supportNew[1] = (c - cStart)*8 + 3+4; 2450 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2451 #if 1 2452 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2453 for (p = 0; p < 2; ++p) { 2454 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); 2455 } 2456 #endif 2457 ++newp; 2458 /* Face E: {d, f, a} */ 2459 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 2460 orntNew[0] = ornt[2] < 0 ? 0 : -2; 2461 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2462 orntNew[1] = -2; 2463 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 2464 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2465 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2466 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2467 #if 1 2468 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2469 for (p = 0; p < 3; ++p) { 2470 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); 2471 } 2472 #endif 2473 supportNew[0] = (c - cStart)*8 + 0+4; 2474 supportNew[1] = (c - cStart)*8 + 3+4; 2475 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2476 #if 1 2477 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2478 for (p = 0; p < 2; ++p) { 2479 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); 2480 } 2481 #endif 2482 ++newp; 2483 /* Face F: {c, a, f} */ 2484 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 2485 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2486 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2487 orntNew[1] = 0; 2488 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 2489 orntNew[2] = ornt[2] < 0 ? 0 : -2; 2490 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2491 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2492 #if 1 2493 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2494 for (p = 0; p < 3; ++p) { 2495 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); 2496 } 2497 #endif 2498 supportNew[0] = (c - cStart)*8 + 0+4; 2499 supportNew[1] = (c - cStart)*8 + 2+4; 2500 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2501 #if 1 2502 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2503 for (p = 0; p < 2; ++p) { 2504 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); 2505 } 2506 #endif 2507 ++newp; 2508 /* Face G: {e, a, f} */ 2509 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 2510 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2511 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2512 orntNew[1] = 0; 2513 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 2514 orntNew[2] = ornt[3] < 0 ? 0 : -2; 2515 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2516 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2517 #if 1 2518 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2519 for (p = 0; p < 3; ++p) { 2520 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); 2521 } 2522 #endif 2523 supportNew[0] = (c - cStart)*8 + 1+4; 2524 supportNew[1] = (c - cStart)*8 + 3+4; 2525 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2526 #if 1 2527 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2528 for (p = 0; p < 2; ++p) { 2529 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); 2530 } 2531 #endif 2532 ++newp; 2533 /* Face H: {a, b, f} */ 2534 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 2535 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2536 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 2537 orntNew[1] = ornt[3] < 0 ? 0 : -2; 2538 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2539 orntNew[2] = -2; 2540 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2541 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2542 #if 1 2543 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2544 for (p = 0; p < 3; ++p) { 2545 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); 2546 } 2547 #endif 2548 supportNew[0] = (c - cStart)*8 + 1+4; 2549 supportNew[1] = (c - cStart)*8 + 2+4; 2550 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2551 #if 1 2552 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2553 for (p = 0; p < 2; ++p) { 2554 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); 2555 } 2556 #endif 2557 ++newp; 2558 } 2559 /* Split Edges have 2 vertices and the same faces as the parent */ 2560 for (e = eStart; e < eEnd; ++e) { 2561 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 2562 2563 for (r = 0; r < 2; ++r) { 2564 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 2565 const PetscInt *cone, *ornt, *support; 2566 PetscInt coneNew[2], coneSize, c, supportSize, s; 2567 2568 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 2569 coneNew[0] = vStartNew + (cone[0] - vStart); 2570 coneNew[1] = vStartNew + (cone[1] - vStart); 2571 coneNew[(r+1)%2] = newv; 2572 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2573 #if 1 2574 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2575 for (p = 0; p < 2; ++p) { 2576 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); 2577 } 2578 #endif 2579 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 2580 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2581 for (s = 0; s < supportSize; ++s) { 2582 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2583 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2584 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2585 for (c = 0; c < coneSize; ++c) { 2586 if (cone[c] == e) break; 2587 } 2588 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 2589 } 2590 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2591 #if 1 2592 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2593 for (p = 0; p < supportSize; ++p) { 2594 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); 2595 } 2596 #endif 2597 } 2598 } 2599 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 2600 for (f = fStart; f < fEnd; ++f) { 2601 const PetscInt *cone, *ornt, *support; 2602 PetscInt coneSize, supportSize, s; 2603 2604 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2605 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2606 for (r = 0; r < 3; ++r) { 2607 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 2608 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 2609 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 2610 -1, -1, 1, 6, 0, 4, 2611 2, 5, 3, 4, -1, -1, 2612 -1, -1, 3, 6, 2, 7}; 2613 2614 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2615 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 2616 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 2617 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2618 #if 1 2619 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2620 for (p = 0; p < 2; ++p) { 2621 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); 2622 } 2623 #endif 2624 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 2625 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 2626 for (s = 0; s < supportSize; ++s) { 2627 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2628 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2629 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2630 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 2631 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 2632 er = GetTetSomethingInverse_Static(ornt[c], r); 2633 if (er == eint[c]) { 2634 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 2635 } else { 2636 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 2637 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 2638 } 2639 } 2640 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2641 #if 1 2642 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2643 for (p = 0; p < intFaces; ++p) { 2644 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); 2645 } 2646 #endif 2647 } 2648 } 2649 /* Interior edges have 2 vertices and 4 faces */ 2650 for (c = cStart; c < cEnd; ++c) { 2651 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2652 const PetscInt *cone, *ornt, *fcone; 2653 PetscInt coneNew[2], supportNew[4], find; 2654 2655 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2656 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2657 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 2658 find = GetTriEdge_Static(ornt[0], 0); 2659 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2660 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 2661 find = GetTriEdge_Static(ornt[2], 1); 2662 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2663 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2664 #if 1 2665 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2666 for (p = 0; p < 2; ++p) { 2667 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); 2668 } 2669 #endif 2670 supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2671 supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2672 supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2673 supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2674 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2675 #if 1 2676 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2677 for (p = 0; p < 4; ++p) { 2678 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); 2679 } 2680 #endif 2681 } 2682 /* Old vertices have identical supports */ 2683 for (v = vStart; v < vEnd; ++v) { 2684 const PetscInt newp = vStartNew + (v - vStart); 2685 const PetscInt *support, *cone; 2686 PetscInt size, s; 2687 2688 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2689 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2690 for (s = 0; s < size; ++s) { 2691 PetscInt r = 0; 2692 2693 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2694 if (cone[1] == v) r = 1; 2695 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 2696 } 2697 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2698 #if 1 2699 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2700 for (p = 0; p < size; ++p) { 2701 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); 2702 } 2703 #endif 2704 } 2705 /* Edge vertices have 2 + face*2 + 0/1 supports */ 2706 for (e = eStart; e < eEnd; ++e) { 2707 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 2708 const PetscInt *cone, *support; 2709 PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 2710 2711 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 2712 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2713 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 2714 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 2715 for (s = 0; s < size; ++s) { 2716 PetscInt r = 0; 2717 2718 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2719 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2720 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 2721 supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 2722 supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 2723 } 2724 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2725 for (s = 0; s < starSize*2; s += 2) { 2726 const PetscInt *cone, *ornt; 2727 PetscInt e01, e23; 2728 2729 if ((star[s] >= cStart) && (star[s] < cEnd)) { 2730 /* Check edge 0-1 */ 2731 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2732 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2733 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 2734 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 2735 /* Check edge 2-3 */ 2736 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2737 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2738 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 2739 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 2740 if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 2741 } 2742 } 2743 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2744 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2745 #if 1 2746 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2747 for (p = 0; p < 2+size*2+cellSize; ++p) { 2748 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); 2749 } 2750 #endif 2751 } 2752 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2753 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 2754 break; 2755 case 7: 2756 /* Hybrid Simplicial 3D */ 2757 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 2758 /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 2759 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 2760 for (c = cStart; c < cMax; ++c) { 2761 const PetscInt newp = cStartNew + (c - cStart)*8; 2762 const PetscInt *cone, *ornt; 2763 PetscInt coneNew[4], orntNew[4]; 2764 2765 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2766 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2767 /* A tetrahedron: {0, a, c, d} */ 2768 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 2769 orntNew[0] = ornt[0]; 2770 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 2771 orntNew[1] = ornt[1]; 2772 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 2773 orntNew[2] = ornt[2]; 2774 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 2775 orntNew[3] = 0; 2776 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2777 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2778 #if 1 2779 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); 2780 for (p = 0; p < 4; ++p) { 2781 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); 2782 } 2783 #endif 2784 /* B tetrahedron: {a, 1, b, e} */ 2785 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 2786 orntNew[0] = ornt[0]; 2787 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 2788 orntNew[1] = ornt[1]; 2789 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 2790 orntNew[2] = 0; 2791 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 2792 orntNew[3] = ornt[3]; 2793 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2794 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2795 #if 1 2796 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); 2797 for (p = 0; p < 4; ++p) { 2798 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); 2799 } 2800 #endif 2801 /* C tetrahedron: {c, b, 2, f} */ 2802 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 2803 orntNew[0] = ornt[0]; 2804 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 2805 orntNew[1] = 0; 2806 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 2807 orntNew[2] = ornt[2]; 2808 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 2809 orntNew[3] = ornt[3]; 2810 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2811 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2812 #if 1 2813 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); 2814 for (p = 0; p < 4; ++p) { 2815 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); 2816 } 2817 #endif 2818 /* D tetrahedron: {d, e, f, 3} */ 2819 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 2820 orntNew[0] = 0; 2821 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 2822 orntNew[1] = ornt[1]; 2823 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 2824 orntNew[2] = ornt[2]; 2825 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 2826 orntNew[3] = ornt[3]; 2827 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2828 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2829 #if 1 2830 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); 2831 for (p = 0; p < 4; ++p) { 2832 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); 2833 } 2834 #endif 2835 /* A' tetrahedron: {d, a, c, f} */ 2836 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 2837 orntNew[0] = -3; 2838 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 2839 orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0); 2840 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 2841 orntNew[2] = 0; 2842 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 2843 orntNew[3] = 2; 2844 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 2845 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 2846 #if 1 2847 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); 2848 for (p = 0; p < 4; ++p) { 2849 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); 2850 } 2851 #endif 2852 /* B' tetrahedron: {e, b, a, f} */ 2853 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 2854 orntNew[0] = -3; 2855 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 2856 orntNew[1] = 1; 2857 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 2858 orntNew[2] = 0; 2859 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 2860 orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0); 2861 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 2862 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 2863 #if 1 2864 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); 2865 for (p = 0; p < 4; ++p) { 2866 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); 2867 } 2868 #endif 2869 /* C' tetrahedron: {b, f, c, a} */ 2870 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 2871 orntNew[0] = -3; 2872 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 2873 orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2); 2874 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 2875 orntNew[2] = -3; 2876 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 2877 orntNew[3] = -2; 2878 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 2879 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 2880 #if 1 2881 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); 2882 for (p = 0; p < 4; ++p) { 2883 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); 2884 } 2885 #endif 2886 /* D' tetrahedron: {f, e, d, a} */ 2887 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 2888 orntNew[0] = -3; 2889 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 2890 orntNew[1] = -3; 2891 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 2892 orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0); 2893 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 2894 orntNew[3] = -3; 2895 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 2896 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 2897 #if 1 2898 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); 2899 for (p = 0; p < 4; ++p) { 2900 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); 2901 } 2902 #endif 2903 } 2904 /* Hybrid cells have 5 faces */ 2905 for (c = cMax; c < cEnd; ++c) { 2906 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4; 2907 const PetscInt *cone, *ornt, *fornt; 2908 PetscInt coneNew[5], orntNew[5], o, of; 2909 2910 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2911 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2912 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 2913 o = ornt[0] < 0 ? -1 : 1; 2914 for (r = 0; r < 3; ++r) { 2915 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 2916 orntNew[0] = ornt[0]; 2917 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 2918 orntNew[1] = ornt[1]; 2919 of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1; 2920 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], (r+2)%3)] - fMax)*2 + (o*of < 0 ? 0 : 1); 2921 orntNew[2] = 0; 2922 of = fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? -1 : 1; 2923 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (o*of < 0 ? 1 : 0); 2924 orntNew[3] = 0; 2925 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 2926 orntNew[4] = 0; 2927 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 2928 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 2929 #if 1 2930 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); 2931 for (p = 0; p < 2; ++p) { 2932 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); 2933 } 2934 for (p = 2; p < 5; ++p) { 2935 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); 2936 } 2937 #endif 2938 } 2939 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 2940 orntNew[0] = 0; 2941 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 2942 orntNew[1] = 0; 2943 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 2944 orntNew[2] = 0; 2945 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 2946 orntNew[3] = 0; 2947 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 2948 orntNew[4] = 0; 2949 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2950 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2951 #if 1 2952 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); 2953 for (p = 0; p < 2; ++p) { 2954 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); 2955 } 2956 for (p = 2; p < 5; ++p) { 2957 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); 2958 } 2959 #endif 2960 } 2961 /* Split faces have 3 edges and the same cells as the parent */ 2962 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2963 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 2964 for (f = fStart; f < fMax; ++f) { 2965 const PetscInt newp = fStartNew + (f - fStart)*4; 2966 const PetscInt *cone, *ornt, *support; 2967 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 2968 2969 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2970 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2971 /* A triangle */ 2972 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 2973 orntNew[0] = ornt[0]; 2974 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 2975 orntNew[1] = -2; 2976 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 2977 orntNew[2] = ornt[2]; 2978 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2979 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2980 #if 1 2981 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); 2982 for (p = 0; p < 3; ++p) { 2983 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); 2984 } 2985 #endif 2986 /* B triangle */ 2987 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 2988 orntNew[0] = ornt[0]; 2989 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 2990 orntNew[1] = ornt[1]; 2991 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 2992 orntNew[2] = -2; 2993 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2994 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2995 #if 1 2996 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); 2997 for (p = 0; p < 3; ++p) { 2998 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); 2999 } 3000 #endif 3001 /* C triangle */ 3002 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3003 orntNew[0] = -2; 3004 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 3005 orntNew[1] = ornt[1]; 3006 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 3007 orntNew[2] = ornt[2]; 3008 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3009 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3010 #if 1 3011 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); 3012 for (p = 0; p < 3; ++p) { 3013 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); 3014 } 3015 #endif 3016 /* D triangle */ 3017 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 3018 orntNew[0] = 0; 3019 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3020 orntNew[1] = 0; 3021 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 3022 orntNew[2] = 0; 3023 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3024 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3025 #if 1 3026 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); 3027 for (p = 0; p < 3; ++p) { 3028 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); 3029 } 3030 #endif 3031 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3032 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3033 for (r = 0; r < 4; ++r) { 3034 for (s = 0; s < supportSize; ++s) { 3035 PetscInt subf; 3036 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3037 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3038 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3039 for (c = 0; c < coneSize; ++c) { 3040 if (cone[c] == f) break; 3041 } 3042 subf = GetTriSubfaceInverse_Static(ornt[c], r); 3043 if (support[s] < cMax) { 3044 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 3045 } else { 3046 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf); 3047 } 3048 } 3049 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 3050 #if 1 3051 if ((newp+r < fStartNew) || (newp+r >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+r, fStartNew, fMaxNew); 3052 for (p = 0; p < supportSize; ++p) { 3053 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); 3054 } 3055 #endif 3056 } 3057 } 3058 /* Interior cell faces have 3 edges and 2 cells */ 3059 for (c = cStart; c < cMax; ++c) { 3060 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 3061 const PetscInt *cone, *ornt; 3062 PetscInt coneNew[3], orntNew[3]; 3063 PetscInt supportNew[2]; 3064 3065 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3066 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3067 /* Face A: {c, a, d} */ 3068 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 3069 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3070 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 3071 orntNew[1] = ornt[1] < 0 ? -2 : 0; 3072 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2); 3073 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3074 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3075 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3076 #if 1 3077 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3078 for (p = 0; p < 3; ++p) { 3079 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); 3080 } 3081 #endif 3082 supportNew[0] = (c - cStart)*8 + 0; 3083 supportNew[1] = (c - cStart)*8 + 0+4; 3084 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3085 #if 1 3086 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3087 for (p = 0; p < 2; ++p) { 3088 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); 3089 } 3090 #endif 3091 ++newp; 3092 /* Face B: {a, b, e} */ 3093 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 3094 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3095 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0); 3096 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3097 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 3098 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3099 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3100 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3101 #if 1 3102 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); 3103 for (p = 0; p < 3; ++p) { 3104 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); 3105 } 3106 #endif 3107 supportNew[0] = (c - cStart)*8 + 1; 3108 supportNew[1] = (c - cStart)*8 + 1+4; 3109 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3110 #if 1 3111 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3112 for (p = 0; p < 2; ++p) { 3113 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); 3114 } 3115 #endif 3116 ++newp; 3117 /* Face C: {c, f, b} */ 3118 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 3119 orntNew[0] = ornt[2] < 0 ? -2 : 0; 3120 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 3121 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3122 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1); 3123 orntNew[2] = ornt[0] < 0 ? -2 : 0; 3124 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3125 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3126 #if 1 3127 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3128 for (p = 0; p < 3; ++p) { 3129 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); 3130 } 3131 #endif 3132 supportNew[0] = (c - cStart)*8 + 2; 3133 supportNew[1] = (c - cStart)*8 + 2+4; 3134 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3135 #if 1 3136 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3137 for (p = 0; p < 2; ++p) { 3138 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); 3139 } 3140 #endif 3141 ++newp; 3142 /* Face D: {d, e, f} */ 3143 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0); 3144 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3145 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 3146 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3147 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 3148 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3149 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3150 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3151 #if 1 3152 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3153 for (p = 0; p < 3; ++p) { 3154 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); 3155 } 3156 #endif 3157 supportNew[0] = (c - cStart)*8 + 3; 3158 supportNew[1] = (c - cStart)*8 + 3+4; 3159 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3160 #if 1 3161 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3162 for (p = 0; p < 2; ++p) { 3163 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); 3164 } 3165 #endif 3166 ++newp; 3167 /* Face E: {d, f, a} */ 3168 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 3169 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3170 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3171 orntNew[1] = -2; 3172 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 3173 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3174 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3175 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3176 #if 1 3177 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3178 for (p = 0; p < 3; ++p) { 3179 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); 3180 } 3181 #endif 3182 supportNew[0] = (c - cStart)*8 + 0+4; 3183 supportNew[1] = (c - cStart)*8 + 3+4; 3184 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3185 #if 1 3186 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3187 for (p = 0; p < 2; ++p) { 3188 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); 3189 } 3190 #endif 3191 ++newp; 3192 /* Face F: {c, a, f} */ 3193 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 3194 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3195 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3196 orntNew[1] = 0; 3197 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 3198 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3199 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3200 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3201 #if 1 3202 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3203 for (p = 0; p < 3; ++p) { 3204 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); 3205 } 3206 #endif 3207 supportNew[0] = (c - cStart)*8 + 0+4; 3208 supportNew[1] = (c - cStart)*8 + 2+4; 3209 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3210 #if 1 3211 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3212 for (p = 0; p < 2; ++p) { 3213 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); 3214 } 3215 #endif 3216 ++newp; 3217 /* Face G: {e, a, f} */ 3218 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 3219 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3220 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3221 orntNew[1] = 0; 3222 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 3223 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3224 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3225 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3226 #if 1 3227 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3228 for (p = 0; p < 3; ++p) { 3229 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); 3230 } 3231 #endif 3232 supportNew[0] = (c - cStart)*8 + 1+4; 3233 supportNew[1] = (c - cStart)*8 + 3+4; 3234 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3235 #if 1 3236 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3237 for (p = 0; p < 2; ++p) { 3238 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); 3239 } 3240 #endif 3241 ++newp; 3242 /* Face H: {a, b, f} */ 3243 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 3244 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3245 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 3246 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3247 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3248 orntNew[2] = -2; 3249 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3250 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3251 #if 1 3252 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3253 for (p = 0; p < 3; ++p) { 3254 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); 3255 } 3256 #endif 3257 supportNew[0] = (c - cStart)*8 + 1+4; 3258 supportNew[1] = (c - cStart)*8 + 2+4; 3259 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3260 #if 1 3261 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3262 for (p = 0; p < 2; ++p) { 3263 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); 3264 } 3265 #endif 3266 ++newp; 3267 } 3268 /* Hybrid split faces have 4 edges and same cells */ 3269 for (f = fMax; f < fEnd; ++f) { 3270 const PetscInt *cone, *ornt, *support; 3271 PetscInt coneNew[4], orntNew[4]; 3272 PetscInt supportNew[2], size, s, c; 3273 3274 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3275 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3276 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3277 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3278 for (r = 0; r < 2; ++r) { 3279 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 3280 3281 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 3282 orntNew[0] = ornt[0]; 3283 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 3284 orntNew[1] = ornt[1]; 3285 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 3286 orntNew[2+r] = 0; 3287 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3288 orntNew[3-r] = 0; 3289 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3290 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3291 #if 1 3292 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3293 for (p = 0; p < 2; ++p) { 3294 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); 3295 } 3296 for (p = 2; p < 4; ++p) { 3297 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); 3298 } 3299 #endif 3300 for (s = 0; s < size; ++s) { 3301 const PetscInt *coneCell, *orntCell, *fornt; 3302 PetscInt o, of; 3303 3304 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 3305 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 3306 o = orntCell[0] < 0 ? -1 : 1; 3307 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 3308 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 3309 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 3310 of = fornt[c-2] < 0 ? -1 : 1; 3311 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 3312 } 3313 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3314 #if 1 3315 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3316 for (p = 0; p < size; ++p) { 3317 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); 3318 } 3319 #endif 3320 } 3321 } 3322 /* Hybrid cell faces have 4 edges and 2 cells */ 3323 for (c = cMax; c < cEnd; ++c) { 3324 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 3325 const PetscInt *cone, *ornt; 3326 PetscInt coneNew[4], orntNew[4]; 3327 PetscInt supportNew[2]; 3328 3329 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3330 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3331 for (r = 0; r < 3; ++r) { 3332 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3; 3333 orntNew[0] = 0; 3334 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3; 3335 orntNew[1] = 0; 3336 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax); 3337 orntNew[2] = 0; 3338 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r] - fMax); 3339 orntNew[3] = 0; 3340 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 3341 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 3342 #if 1 3343 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); 3344 for (p = 0; p < 2; ++p) { 3345 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); 3346 } 3347 for (p = 2; p < 4; ++p) { 3348 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); 3349 } 3350 #endif 3351 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 3352 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 3353 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 3354 #if 1 3355 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); 3356 for (p = 0; p < 2; ++p) { 3357 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); 3358 } 3359 #endif 3360 } 3361 } 3362 /* Interior split edges have 2 vertices and the same faces as the parent */ 3363 for (e = eStart; e < eMax; ++e) { 3364 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3365 3366 for (r = 0; r < 2; ++r) { 3367 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3368 const PetscInt *cone, *ornt, *support; 3369 PetscInt coneNew[2], coneSize, c, supportSize, s; 3370 3371 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3372 coneNew[0] = vStartNew + (cone[0] - vStart); 3373 coneNew[1] = vStartNew + (cone[1] - vStart); 3374 coneNew[(r+1)%2] = newv; 3375 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3376 #if 1 3377 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3378 for (p = 0; p < 2; ++p) { 3379 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); 3380 } 3381 #endif 3382 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3383 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3384 for (s = 0; s < supportSize; ++s) { 3385 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3386 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3387 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3388 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 3389 if (support[s] < fMax) { 3390 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 3391 } else { 3392 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 3393 } 3394 } 3395 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3396 #if 1 3397 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3398 for (p = 0; p < supportSize; ++p) { 3399 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); 3400 } 3401 #endif 3402 } 3403 } 3404 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 3405 for (f = fStart; f < fMax; ++f) { 3406 const PetscInt *cone, *ornt, *support; 3407 PetscInt coneSize, supportSize, s; 3408 3409 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3410 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3411 for (r = 0; r < 3; ++r) { 3412 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 3413 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 3414 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 3415 -1, -1, 1, 6, 0, 4, 3416 2, 5, 3, 4, -1, -1, 3417 -1, -1, 3, 6, 2, 7}; 3418 3419 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3420 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 3421 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 3422 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3423 #if 1 3424 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3425 for (p = 0; p < 2; ++p) { 3426 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); 3427 } 3428 #endif 3429 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 3430 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 3431 for (s = 0; s < supportSize; ++s) { 3432 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3433 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3434 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3435 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 3436 if (support[s] < cMax) { 3437 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 3438 er = GetTetSomethingInverse_Static(ornt[c], r); 3439 if (er == eint[c]) { 3440 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 3441 } else { 3442 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 3443 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 3444 } 3445 } else { 3446 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3; 3447 } 3448 } 3449 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3450 #if 1 3451 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3452 for (p = 0; p < intFaces; ++p) { 3453 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); 3454 } 3455 #endif 3456 } 3457 } 3458 /* Interior cell edges have 2 vertices and 4 faces */ 3459 for (c = cStart; c < cMax; ++c) { 3460 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3461 const PetscInt *cone, *ornt, *fcone; 3462 PetscInt coneNew[2], supportNew[4], find; 3463 3464 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3465 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3466 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 3467 find = GetTriEdge_Static(ornt[0], 0); 3468 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3469 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 3470 find = GetTriEdge_Static(ornt[2], 1); 3471 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3472 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3473 #if 1 3474 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3475 for (p = 0; p < 2; ++p) { 3476 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); 3477 } 3478 #endif 3479 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3480 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3481 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3482 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3483 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3484 #if 1 3485 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3486 for (p = 0; p < 4; ++p) { 3487 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); 3488 } 3489 #endif 3490 } 3491 /* Hybrid edges have two vertices and the same faces */ 3492 for (e = eMax; e < eEnd; ++e) { 3493 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 3494 const PetscInt *cone, *support, *fcone; 3495 PetscInt coneNew[2], size, fsize, s; 3496 3497 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3498 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3499 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3500 coneNew[0] = vStartNew + (cone[0] - vStart); 3501 coneNew[1] = vStartNew + (cone[1] - vStart); 3502 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3503 #if 1 3504 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3505 for (p = 0; p < 2; ++p) { 3506 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); 3507 } 3508 #endif 3509 for (s = 0; s < size; ++s) { 3510 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 3511 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 3512 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 3513 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 3514 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 3515 } 3516 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3517 #if 1 3518 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3519 for (p = 0; p < size; ++p) { 3520 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); 3521 } 3522 #endif 3523 } 3524 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 3525 for (f = fMax; f < fEnd; ++f) { 3526 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3527 const PetscInt *cone, *support, *ccone, *cornt; 3528 PetscInt coneNew[2], size, csize, s; 3529 3530 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3531 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3532 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3533 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 3534 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 3535 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3536 #if 1 3537 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3538 for (p = 0; p < 2; ++p) { 3539 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); 3540 } 3541 #endif 3542 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 3543 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 3544 for (s = 0; s < size; ++s) { 3545 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 3546 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 3547 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 3548 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 3549 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]); 3550 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2; 3551 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3; 3552 } 3553 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3554 #if 1 3555 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3556 for (p = 0; p < 2+size*2; ++p) { 3557 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); 3558 } 3559 #endif 3560 } 3561 /* Interior vertices have identical supports */ 3562 for (v = vStart; v < vEnd; ++v) { 3563 const PetscInt newp = vStartNew + (v - vStart); 3564 const PetscInt *support, *cone; 3565 PetscInt size, s; 3566 3567 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3568 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3569 for (s = 0; s < size; ++s) { 3570 PetscInt r = 0; 3571 3572 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3573 if (cone[1] == v) r = 1; 3574 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3575 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 3576 } 3577 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3578 #if 1 3579 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3580 for (p = 0; p < size; ++p) { 3581 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); 3582 } 3583 #endif 3584 } 3585 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 3586 for (e = eStart; e < eMax; ++e) { 3587 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3588 const PetscInt *cone, *support; 3589 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 3590 3591 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3592 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3593 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3594 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3595 for (s = 0; s < size; ++s) { 3596 PetscInt r = 0; 3597 3598 if (support[s] < fMax) { 3599 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3600 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3601 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 3602 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 3603 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 3604 faceSize += 2; 3605 } else { 3606 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 3607 ++faceSize; 3608 } 3609 } 3610 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3611 for (s = 0; s < starSize*2; s += 2) { 3612 const PetscInt *cone, *ornt; 3613 PetscInt e01, e23; 3614 3615 if ((star[s] >= cStart) && (star[s] < cMax)) { 3616 /* Check edge 0-1 */ 3617 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3618 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3619 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 3620 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 3621 /* Check edge 2-3 */ 3622 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3623 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3624 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 3625 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 3626 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 3627 } 3628 } 3629 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3630 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3631 #if 1 3632 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3633 for (p = 0; p < 2+faceSize+cellSize; ++p) { 3634 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); 3635 } 3636 #endif 3637 } 3638 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3639 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 3640 break; 3641 case 6: 3642 /* Hex 3D */ 3643 /* 3644 Bottom (viewed from top) Top 3645 1---------2---------2 7---------2---------6 3646 | | | | | | 3647 | B 2 C | | H 2 G | 3648 | | | | | | 3649 3----3----0----1----1 3----3----0----1----1 3650 | | | | | | 3651 | A 0 D | | E 0 F | 3652 | | | | | | 3653 0---------0---------3 4---------0---------5 3654 */ 3655 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 3656 for (c = cStart; c < cEnd; ++c) { 3657 const PetscInt newp = (c - cStart)*8; 3658 const PetscInt *cone, *ornt; 3659 PetscInt coneNew[6], orntNew[6]; 3660 3661 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3662 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3663 /* A hex */ 3664 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 3665 orntNew[0] = ornt[0]; 3666 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3667 orntNew[1] = 0; 3668 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 3669 orntNew[2] = ornt[2]; 3670 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3671 orntNew[3] = 0; 3672 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3673 orntNew[4] = 0; 3674 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 3675 orntNew[5] = ornt[5]; 3676 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3677 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3678 #if 1 3679 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); 3680 for (p = 0; p < 6; ++p) { 3681 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); 3682 } 3683 #endif 3684 /* B hex */ 3685 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 3686 orntNew[0] = ornt[0]; 3687 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3688 orntNew[1] = 0; 3689 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3690 orntNew[2] = -1; 3691 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 3692 orntNew[3] = ornt[3]; 3693 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3694 orntNew[4] = 0; 3695 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 3696 orntNew[5] = ornt[5]; 3697 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3698 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3699 #if 1 3700 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); 3701 for (p = 0; p < 6; ++p) { 3702 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); 3703 } 3704 #endif 3705 /* C hex */ 3706 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 3707 orntNew[0] = ornt[0]; 3708 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3709 orntNew[1] = 0; 3710 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3711 orntNew[2] = -1; 3712 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 3713 orntNew[3] = ornt[3]; 3714 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 3715 orntNew[4] = ornt[4]; 3716 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3717 orntNew[5] = -4; 3718 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3719 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3720 #if 1 3721 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); 3722 for (p = 0; p < 6; ++p) { 3723 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); 3724 } 3725 #endif 3726 /* D hex */ 3727 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 3728 orntNew[0] = ornt[0]; 3729 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3730 orntNew[1] = 0; 3731 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 3732 orntNew[2] = ornt[2]; 3733 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3734 orntNew[3] = 0; 3735 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 3736 orntNew[4] = ornt[4]; 3737 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3738 orntNew[5] = -4; 3739 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3740 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3741 #if 1 3742 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); 3743 for (p = 0; p < 6; ++p) { 3744 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); 3745 } 3746 #endif 3747 /* E hex */ 3748 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3749 orntNew[0] = -4; 3750 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 3751 orntNew[1] = ornt[1]; 3752 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 3753 orntNew[2] = ornt[2]; 3754 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3755 orntNew[3] = 0; 3756 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3757 orntNew[4] = -1; 3758 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 3759 orntNew[5] = ornt[5]; 3760 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3761 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3762 #if 1 3763 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); 3764 for (p = 0; p < 6; ++p) { 3765 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); 3766 } 3767 #endif 3768 /* F hex */ 3769 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3770 orntNew[0] = -4; 3771 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 3772 orntNew[1] = ornt[1]; 3773 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 3774 orntNew[2] = ornt[2]; 3775 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3776 orntNew[3] = -1; 3777 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 3778 orntNew[4] = ornt[4]; 3779 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3780 orntNew[5] = 1; 3781 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3782 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3783 #if 1 3784 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); 3785 for (p = 0; p < 6; ++p) { 3786 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); 3787 } 3788 #endif 3789 /* G hex */ 3790 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3791 orntNew[0] = -4; 3792 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 3793 orntNew[1] = ornt[1]; 3794 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3795 orntNew[2] = 0; 3796 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 3797 orntNew[3] = ornt[3]; 3798 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 3799 orntNew[4] = ornt[4]; 3800 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3801 orntNew[5] = -3; 3802 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3803 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3804 #if 1 3805 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); 3806 for (p = 0; p < 6; ++p) { 3807 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); 3808 } 3809 #endif 3810 /* H hex */ 3811 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3812 orntNew[0] = -4; 3813 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 3814 orntNew[1] = ornt[1]; 3815 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3816 orntNew[2] = -1; 3817 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 3818 orntNew[3] = ornt[3]; 3819 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3820 orntNew[4] = 3; 3821 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 3822 orntNew[5] = ornt[5]; 3823 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3824 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3825 #if 1 3826 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); 3827 for (p = 0; p < 6; ++p) { 3828 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); 3829 } 3830 #endif 3831 } 3832 /* Split faces have 4 edges and the same cells as the parent */ 3833 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3834 ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 3835 for (f = fStart; f < fEnd; ++f) { 3836 for (r = 0; r < 4; ++r) { 3837 /* TODO: This can come from GetFaces_Internal() */ 3838 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}; 3839 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 3840 const PetscInt *cone, *ornt, *support; 3841 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 3842 3843 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3844 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3845 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 3846 orntNew[(r+3)%4] = ornt[(r+3)%4]; 3847 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 3848 orntNew[(r+0)%4] = ornt[r]; 3849 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 3850 orntNew[(r+1)%4] = 0; 3851 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 3852 orntNew[(r+2)%4] = -2; 3853 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3854 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3855 #if 1 3856 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3857 for (p = 0; p < 4; ++p) { 3858 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); 3859 } 3860 #endif 3861 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3862 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3863 for (s = 0; s < supportSize; ++s) { 3864 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3865 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3866 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3867 for (c = 0; c < coneSize; ++c) { 3868 if (cone[c] == f) break; 3869 } 3870 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 3871 } 3872 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3873 #if 1 3874 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3875 for (p = 0; p < supportSize; ++p) { 3876 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); 3877 } 3878 #endif 3879 } 3880 } 3881 /* Interior faces have 4 edges and 2 cells */ 3882 for (c = cStart; c < cEnd; ++c) { 3883 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}; 3884 const PetscInt *cone, *ornt; 3885 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 3886 3887 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3888 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3889 /* A-D face */ 3890 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 3891 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 3892 orntNew[0] = 0; 3893 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3894 orntNew[1] = 0; 3895 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3896 orntNew[2] = -2; 3897 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 3898 orntNew[3] = -2; 3899 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3900 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3901 #if 1 3902 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3903 for (p = 0; p < 4; ++p) { 3904 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); 3905 } 3906 #endif 3907 /* C-D face */ 3908 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 3909 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 3910 orntNew[0] = 0; 3911 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3912 orntNew[1] = 0; 3913 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3914 orntNew[2] = -2; 3915 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 3916 orntNew[3] = -2; 3917 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3918 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3919 #if 1 3920 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3921 for (p = 0; p < 4; ++p) { 3922 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); 3923 } 3924 #endif 3925 /* B-C face */ 3926 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 3927 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 3928 orntNew[0] = -2; 3929 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 3930 orntNew[1] = 0; 3931 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3932 orntNew[2] = 0; 3933 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3934 orntNew[3] = -2; 3935 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3936 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3937 #if 1 3938 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3939 for (p = 0; p < 4; ++p) { 3940 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); 3941 } 3942 #endif 3943 /* A-B face */ 3944 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 3945 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 3946 orntNew[0] = -2; 3947 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 3948 orntNew[1] = 0; 3949 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3950 orntNew[2] = 0; 3951 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3952 orntNew[3] = -2; 3953 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3954 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3955 #if 1 3956 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3957 for (p = 0; p < 4; ++p) { 3958 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); 3959 } 3960 #endif 3961 /* E-F face */ 3962 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 3963 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3964 orntNew[0] = -2; 3965 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 3966 orntNew[1] = -2; 3967 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 3968 orntNew[2] = 0; 3969 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3970 orntNew[3] = 0; 3971 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3972 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3973 #if 1 3974 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3975 for (p = 0; p < 4; ++p) { 3976 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); 3977 } 3978 #endif 3979 /* F-G face */ 3980 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 3981 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3982 orntNew[0] = -2; 3983 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 3984 orntNew[1] = -2; 3985 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 3986 orntNew[2] = 0; 3987 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3988 orntNew[3] = 0; 3989 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3990 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3991 #if 1 3992 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3993 for (p = 0; p < 4; ++p) { 3994 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); 3995 } 3996 #endif 3997 /* G-H face */ 3998 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 3999 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 4000 orntNew[0] = -2; 4001 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 4002 orntNew[1] = 0; 4003 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4004 orntNew[2] = 0; 4005 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4006 orntNew[3] = -2; 4007 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4008 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4009 #if 1 4010 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4011 for (p = 0; p < 4; ++p) { 4012 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); 4013 } 4014 #endif 4015 /* E-H face */ 4016 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 4017 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4018 orntNew[0] = -2; 4019 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 4020 orntNew[1] = -2; 4021 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 4022 orntNew[2] = 0; 4023 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4024 orntNew[3] = 0; 4025 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4026 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4027 #if 1 4028 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4029 for (p = 0; p < 4; ++p) { 4030 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); 4031 } 4032 #endif 4033 /* A-E face */ 4034 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 4035 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 4036 orntNew[0] = 0; 4037 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4038 orntNew[1] = 0; 4039 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4040 orntNew[2] = -2; 4041 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 4042 orntNew[3] = -2; 4043 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4044 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4045 #if 1 4046 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4047 for (p = 0; p < 4; ++p) { 4048 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); 4049 } 4050 #endif 4051 /* D-F face */ 4052 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 4053 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 4054 orntNew[0] = -2; 4055 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 4056 orntNew[1] = 0; 4057 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4058 orntNew[2] = 0; 4059 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4060 orntNew[3] = -2; 4061 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4062 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4063 #if 1 4064 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4065 for (p = 0; p < 4; ++p) { 4066 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); 4067 } 4068 #endif 4069 /* C-G face */ 4070 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 4071 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4072 orntNew[0] = -2; 4073 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 4074 orntNew[1] = -2; 4075 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 4076 orntNew[2] = 0; 4077 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4078 orntNew[3] = 0; 4079 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4080 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4081 #if 1 4082 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4083 for (p = 0; p < 4; ++p) { 4084 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); 4085 } 4086 #endif 4087 /* B-H face */ 4088 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 4089 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4090 orntNew[0] = 0; 4091 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4092 orntNew[1] = -2; 4093 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 4094 orntNew[2] = -2; 4095 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 4096 orntNew[3] = 0; 4097 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4098 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4099 #if 1 4100 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4101 for (p = 0; p < 4; ++p) { 4102 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); 4103 } 4104 #endif 4105 for (r = 0; r < 12; ++r) { 4106 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 4107 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 4108 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 4109 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4110 #if 1 4111 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4112 for (p = 0; p < 2; ++p) { 4113 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); 4114 } 4115 #endif 4116 } 4117 } 4118 /* Split edges have 2 vertices and the same faces as the parent */ 4119 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4120 for (e = eStart; e < eEnd; ++e) { 4121 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4122 4123 for (r = 0; r < 2; ++r) { 4124 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4125 const PetscInt *cone, *ornt, *support; 4126 PetscInt coneNew[2], coneSize, c, supportSize, s; 4127 4128 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4129 coneNew[0] = vStartNew + (cone[0] - vStart); 4130 coneNew[1] = vStartNew + (cone[1] - vStart); 4131 coneNew[(r+1)%2] = newv; 4132 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4133 #if 1 4134 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4135 for (p = 0; p < 2; ++p) { 4136 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); 4137 } 4138 #endif 4139 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4140 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4141 for (s = 0; s < supportSize; ++s) { 4142 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4143 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4144 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4145 for (c = 0; c < coneSize; ++c) { 4146 if (cone[c] == e) break; 4147 } 4148 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 4149 } 4150 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4151 #if 1 4152 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4153 for (p = 0; p < supportSize; ++p) { 4154 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); 4155 } 4156 #endif 4157 } 4158 } 4159 /* Face edges have 2 vertices and 2+cells faces */ 4160 for (f = fStart; f < fEnd; ++f) { 4161 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}; 4162 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 4163 const PetscInt *cone, *coneCell, *orntCell, *support; 4164 PetscInt coneNew[2], coneSize, c, supportSize, s; 4165 4166 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4167 for (r = 0; r < 4; ++r) { 4168 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 4169 4170 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 4171 coneNew[1] = newv; 4172 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4173 #if 1 4174 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4175 for (p = 0; p < 2; ++p) { 4176 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); 4177 } 4178 #endif 4179 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4180 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4181 supportRef[0] = fStartNew + (f - fStart)*4 + r; 4182 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 4183 for (s = 0; s < supportSize; ++s) { 4184 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4185 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4186 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4187 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 4188 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 4189 } 4190 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4191 #if 1 4192 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4193 for (p = 0; p < 2+supportSize; ++p) { 4194 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); 4195 } 4196 #endif 4197 } 4198 } 4199 /* Cell edges have 2 vertices and 4 faces */ 4200 for (c = cStart; c < cEnd; ++c) { 4201 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}; 4202 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 4203 const PetscInt *cone; 4204 PetscInt coneNew[2], supportNew[4]; 4205 4206 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4207 for (r = 0; r < 6; ++r) { 4208 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 4209 4210 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 4211 coneNew[1] = newv; 4212 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4213 #if 1 4214 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4215 for (p = 0; p < 2; ++p) { 4216 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); 4217 } 4218 #endif 4219 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 4220 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4221 #if 1 4222 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4223 for (p = 0; p < 4; ++p) { 4224 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); 4225 } 4226 #endif 4227 } 4228 } 4229 /* Old vertices have identical supports */ 4230 for (v = vStart; v < vEnd; ++v) { 4231 const PetscInt newp = vStartNew + (v - vStart); 4232 const PetscInt *support, *cone; 4233 PetscInt size, s; 4234 4235 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4236 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4237 for (s = 0; s < size; ++s) { 4238 PetscInt r = 0; 4239 4240 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4241 if (cone[1] == v) r = 1; 4242 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4243 } 4244 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4245 #if 1 4246 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4247 for (p = 0; p < size; ++p) { 4248 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); 4249 } 4250 #endif 4251 } 4252 /* Edge vertices have 2 + faces supports */ 4253 for (e = eStart; e < eEnd; ++e) { 4254 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4255 const PetscInt *cone, *support; 4256 PetscInt size, s; 4257 4258 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4259 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4260 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4261 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4262 for (s = 0; s < size; ++s) { 4263 PetscInt r; 4264 4265 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4266 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 4267 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 4268 } 4269 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4270 #if 1 4271 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4272 for (p = 0; p < 2+size; ++p) { 4273 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); 4274 } 4275 #endif 4276 } 4277 /* Face vertices have 4 + cells supports */ 4278 for (f = fStart; f < fEnd; ++f) { 4279 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 4280 const PetscInt *cone, *support; 4281 PetscInt size, s; 4282 4283 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4284 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4285 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 4286 for (s = 0; s < size; ++s) { 4287 PetscInt r; 4288 4289 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4290 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 4291 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 4292 } 4293 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4294 #if 1 4295 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4296 for (p = 0; p < 4+size; ++p) { 4297 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); 4298 } 4299 #endif 4300 } 4301 /* Cell vertices have 6 supports */ 4302 for (c = cStart; c < cEnd; ++c) { 4303 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 4304 PetscInt supportNew[6]; 4305 4306 for (r = 0; r < 6; ++r) { 4307 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 4308 } 4309 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4310 } 4311 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4312 break; 4313 case 8: 4314 /* Hybrid Hex 3D */ 4315 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 4316 /* 4317 Bottom (viewed from top) Top 4318 1---------2---------2 7---------2---------6 4319 | | | | | | 4320 | B 2 C | | H 2 G | 4321 | | | | | | 4322 3----3----0----1----1 3----3----0----1----1 4323 | | | | | | 4324 | A 0 D | | E 0 F | 4325 | | | | | | 4326 0---------0---------3 4---------0---------5 4327 */ 4328 /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 4329 for (c = cStart; c < cMax; ++c) { 4330 const PetscInt newp = (c - cStart)*8; 4331 const PetscInt *cone, *ornt; 4332 PetscInt coneNew[6], orntNew[6]; 4333 4334 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4335 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4336 /* A hex */ 4337 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 4338 orntNew[0] = ornt[0]; 4339 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4340 orntNew[1] = 0; 4341 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 4342 orntNew[2] = ornt[2]; 4343 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4344 orntNew[3] = 0; 4345 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4346 orntNew[4] = 0; 4347 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 4348 orntNew[5] = ornt[5]; 4349 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4350 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4351 #if 1 4352 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); 4353 for (p = 0; p < 6; ++p) { 4354 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); 4355 } 4356 #endif 4357 /* B hex */ 4358 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 4359 orntNew[0] = ornt[0]; 4360 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4361 orntNew[1] = 0; 4362 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4363 orntNew[2] = -1; 4364 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 4365 orntNew[3] = ornt[3]; 4366 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4367 orntNew[4] = 0; 4368 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 4369 orntNew[5] = ornt[5]; 4370 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4371 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4372 #if 1 4373 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); 4374 for (p = 0; p < 6; ++p) { 4375 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); 4376 } 4377 #endif 4378 /* C hex */ 4379 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 4380 orntNew[0] = ornt[0]; 4381 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4382 orntNew[1] = 0; 4383 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4384 orntNew[2] = -1; 4385 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 4386 orntNew[3] = ornt[3]; 4387 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 4388 orntNew[4] = ornt[4]; 4389 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4390 orntNew[5] = -4; 4391 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4392 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4393 #if 1 4394 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); 4395 for (p = 0; p < 6; ++p) { 4396 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); 4397 } 4398 #endif 4399 /* D hex */ 4400 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 4401 orntNew[0] = ornt[0]; 4402 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4403 orntNew[1] = 0; 4404 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 4405 orntNew[2] = ornt[2]; 4406 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4407 orntNew[3] = 0; 4408 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 4409 orntNew[4] = ornt[4]; 4410 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4411 orntNew[5] = -4; 4412 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4413 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4414 #if 1 4415 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); 4416 for (p = 0; p < 6; ++p) { 4417 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); 4418 } 4419 #endif 4420 /* E hex */ 4421 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4422 orntNew[0] = -4; 4423 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 4424 orntNew[1] = ornt[1]; 4425 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 4426 orntNew[2] = ornt[2]; 4427 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4428 orntNew[3] = 0; 4429 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4430 orntNew[4] = -1; 4431 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 4432 orntNew[5] = ornt[5]; 4433 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 4434 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 4435 #if 1 4436 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); 4437 for (p = 0; p < 6; ++p) { 4438 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); 4439 } 4440 #endif 4441 /* F hex */ 4442 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4443 orntNew[0] = -4; 4444 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 4445 orntNew[1] = ornt[1]; 4446 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 4447 orntNew[2] = ornt[2]; 4448 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4449 orntNew[3] = -1; 4450 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 4451 orntNew[4] = ornt[4]; 4452 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4453 orntNew[5] = 1; 4454 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 4455 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 4456 #if 1 4457 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); 4458 for (p = 0; p < 6; ++p) { 4459 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); 4460 } 4461 #endif 4462 /* G hex */ 4463 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4464 orntNew[0] = -4; 4465 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 4466 orntNew[1] = ornt[1]; 4467 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4468 orntNew[2] = 0; 4469 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 4470 orntNew[3] = ornt[3]; 4471 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 4472 orntNew[4] = ornt[4]; 4473 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4474 orntNew[5] = -3; 4475 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 4476 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 4477 #if 1 4478 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); 4479 for (p = 0; p < 6; ++p) { 4480 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); 4481 } 4482 #endif 4483 /* H hex */ 4484 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4485 orntNew[0] = -4; 4486 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 4487 orntNew[1] = ornt[1]; 4488 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4489 orntNew[2] = -1; 4490 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 4491 orntNew[3] = ornt[3]; 4492 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4493 orntNew[4] = 3; 4494 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 4495 orntNew[5] = ornt[5]; 4496 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 4497 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 4498 #if 1 4499 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); 4500 for (p = 0; p < 6; ++p) { 4501 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); 4502 } 4503 #endif 4504 } 4505 /* Hybrid cells have 6 faces: Front, Back, Sides */ 4506 /* 4507 3---------2---------2 4508 | | | 4509 | D 2 C | 4510 | | | 4511 3----3----0----1----1 4512 | | | 4513 | A 0 B | 4514 | | | 4515 0---------0---------1 4516 */ 4517 for (c = cMax; c < cEnd; ++c) { 4518 const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4; 4519 const PetscInt *cone, *ornt, *fornt; 4520 PetscInt coneNew[6], orntNew[6]; 4521 4522 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4523 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4524 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 4525 for (r = 0; r < 4; ++r) { 4526 PetscInt subfA = GetQuadSubface_Static(ornt[0], r); 4527 PetscInt edgeA = GetQuadEdge_Static(ornt[0], r); 4528 PetscInt edgeB = (edgeA+3)%4; 4529 if (ornt[0] != ornt[1]) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent ordering for matching ends of hybrid cell %d: %d != %d", c, ornt[0], ornt[1]); 4530 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA; 4531 orntNew[0] = ornt[0]; 4532 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA; 4533 orntNew[1] = ornt[0]; 4534 coneNew[(r+0)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[edgeA+2] - fMax)*2 + (fornt[edgeA] < 0 ? 1 : 0); 4535 orntNew[(r+0)%4+2] = ornt[edgeA]; 4536 coneNew[(r+1)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA; 4537 orntNew[(r+1)%4+2] = 0; 4538 coneNew[(r+2)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB; 4539 orntNew[(r+2)%4+2] = -2; 4540 coneNew[(r+3)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[edgeB+2] - fMax)*2 + (fornt[edgeB] < 0 ? 0 : 1); 4541 orntNew[(r+3)%4+2] = ornt[edgeB]; 4542 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4543 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4544 #if 1 4545 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); 4546 for (p = 0; p < 2; ++p) { 4547 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); 4548 } 4549 for (p = 2; p < 6; ++p) { 4550 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); 4551 } 4552 #endif 4553 } 4554 } 4555 /* Interior split faces have 4 edges and the same cells as the parent */ 4556 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4557 ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 4558 for (f = fStart; f < fMax; ++f) { 4559 for (r = 0; r < 4; ++r) { 4560 /* TODO: This can come from GetFaces_Internal() */ 4561 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}; 4562 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 4563 const PetscInt *cone, *ornt, *support; 4564 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 4565 4566 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4567 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4568 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 4569 orntNew[(r+3)%4] = ornt[(r+3)%4]; 4570 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 4571 orntNew[(r+0)%4] = ornt[r]; 4572 coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 4573 orntNew[(r+1)%4] = 0; 4574 coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4; 4575 orntNew[(r+2)%4] = -2; 4576 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4577 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4578 #if 1 4579 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4580 for (p = 0; p < 4; ++p) { 4581 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); 4582 } 4583 #endif 4584 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4585 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4586 for (s = 0; s < supportSize; ++s) { 4587 PetscInt subf; 4588 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4589 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4590 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4591 for (c = 0; c < coneSize; ++c) { 4592 if (cone[c] == f) break; 4593 } 4594 subf = GetQuadSubfaceInverse_Static(ornt[c], r); 4595 if (support[s] < cMax) { 4596 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf]; 4597 } else { 4598 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf; 4599 } 4600 } 4601 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4602 #if 1 4603 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4604 for (p = 0; p < supportSize; ++p) { 4605 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); 4606 } 4607 #endif 4608 } 4609 } 4610 /* Interior faces have 4 edges and 2 cells */ 4611 for (c = cStart; c < cMax; ++c) { 4612 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}; 4613 const PetscInt *cone, *ornt; 4614 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 4615 4616 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4617 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4618 /* A-D face */ 4619 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; 4620 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 4621 orntNew[0] = 0; 4622 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4623 orntNew[1] = 0; 4624 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4625 orntNew[2] = -2; 4626 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 4627 orntNew[3] = -2; 4628 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4629 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4630 #if 1 4631 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4632 for (p = 0; p < 4; ++p) { 4633 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); 4634 } 4635 #endif 4636 /* C-D face */ 4637 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; 4638 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 4639 orntNew[0] = 0; 4640 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4641 orntNew[1] = 0; 4642 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4643 orntNew[2] = -2; 4644 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 4645 orntNew[3] = -2; 4646 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4647 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4648 #if 1 4649 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4650 for (p = 0; p < 4; ++p) { 4651 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); 4652 } 4653 #endif 4654 /* B-C face */ 4655 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; 4656 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 4657 orntNew[0] = -2; 4658 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 4659 orntNew[1] = 0; 4660 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4661 orntNew[2] = 0; 4662 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4663 orntNew[3] = -2; 4664 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4665 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4666 #if 1 4667 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4668 for (p = 0; p < 4; ++p) { 4669 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); 4670 } 4671 #endif 4672 /* A-B face */ 4673 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; 4674 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 4675 orntNew[0] = -2; 4676 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 4677 orntNew[1] = 0; 4678 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4679 orntNew[2] = 0; 4680 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4681 orntNew[3] = -2; 4682 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4683 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4684 #if 1 4685 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4686 for (p = 0; p < 4; ++p) { 4687 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); 4688 } 4689 #endif 4690 /* E-F face */ 4691 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; 4692 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4693 orntNew[0] = -2; 4694 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 4695 orntNew[1] = -2; 4696 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 4697 orntNew[2] = 0; 4698 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4699 orntNew[3] = 0; 4700 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4701 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4702 #if 1 4703 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4704 for (p = 0; p < 4; ++p) { 4705 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); 4706 } 4707 #endif 4708 /* F-G face */ 4709 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; 4710 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4711 orntNew[0] = -2; 4712 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 4713 orntNew[1] = -2; 4714 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 4715 orntNew[2] = 0; 4716 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4717 orntNew[3] = 0; 4718 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4719 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4720 #if 1 4721 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4722 for (p = 0; p < 4; ++p) { 4723 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); 4724 } 4725 #endif 4726 /* G-H face */ 4727 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; 4728 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 4729 orntNew[0] = -2; 4730 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 4731 orntNew[1] = 0; 4732 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4733 orntNew[2] = 0; 4734 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4735 orntNew[3] = -2; 4736 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4737 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4738 #if 1 4739 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4740 for (p = 0; p < 4; ++p) { 4741 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); 4742 } 4743 #endif 4744 /* E-H face */ 4745 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; 4746 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4747 orntNew[0] = -2; 4748 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 4749 orntNew[1] = -2; 4750 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 4751 orntNew[2] = 0; 4752 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4753 orntNew[3] = 0; 4754 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4755 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4756 #if 1 4757 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4758 for (p = 0; p < 4; ++p) { 4759 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); 4760 } 4761 #endif 4762 /* A-E face */ 4763 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; 4764 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 4765 orntNew[0] = 0; 4766 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4767 orntNew[1] = 0; 4768 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4769 orntNew[2] = -2; 4770 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 4771 orntNew[3] = -2; 4772 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4773 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4774 #if 1 4775 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4776 for (p = 0; p < 4; ++p) { 4777 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); 4778 } 4779 #endif 4780 /* D-F face */ 4781 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; 4782 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 4783 orntNew[0] = -2; 4784 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 4785 orntNew[1] = 0; 4786 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4787 orntNew[2] = 0; 4788 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4789 orntNew[3] = -2; 4790 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4791 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4792 #if 1 4793 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4794 for (p = 0; p < 4; ++p) { 4795 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); 4796 } 4797 #endif 4798 /* C-G face */ 4799 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; 4800 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4801 orntNew[0] = -2; 4802 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 4803 orntNew[1] = -2; 4804 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 4805 orntNew[2] = 0; 4806 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4807 orntNew[3] = 0; 4808 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4809 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4810 #if 1 4811 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4812 for (p = 0; p < 4; ++p) { 4813 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); 4814 } 4815 #endif 4816 /* B-H face */ 4817 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; 4818 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4819 orntNew[0] = 0; 4820 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4821 orntNew[1] = -2; 4822 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 4823 orntNew[2] = -2; 4824 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 4825 orntNew[3] = 0; 4826 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4827 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4828 #if 1 4829 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4830 for (p = 0; p < 4; ++p) { 4831 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); 4832 } 4833 #endif 4834 for (r = 0; r < 12; ++r) { 4835 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 4836 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 4837 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 4838 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4839 #if 1 4840 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4841 for (p = 0; p < 2; ++p) { 4842 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); 4843 } 4844 #endif 4845 } 4846 } 4847 /* Hybrid split faces have 4 edges and same cells */ 4848 for (f = fMax; f < fEnd; ++f) { 4849 const PetscInt *cone, *ornt, *support; 4850 PetscInt coneNew[4], orntNew[4]; 4851 PetscInt supportNew[2], size, s, c; 4852 4853 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4854 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4855 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4856 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4857 for (r = 0; r < 2; ++r) { 4858 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 4859 4860 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 4861 orntNew[0] = ornt[0]; 4862 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 4863 orntNew[1] = ornt[1]; 4864 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax); 4865 orntNew[2+r] = 0; 4866 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 4867 orntNew[3-r] = 0; 4868 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4869 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4870 #if 1 4871 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 4872 for (p = 0; p < 2; ++p) { 4873 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); 4874 } 4875 for (p = 2; p < 4; ++p) { 4876 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); 4877 } 4878 #endif 4879 for (s = 0; s < size; ++s) { 4880 const PetscInt *coneCell, *orntCell, *fornt; 4881 4882 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4883 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4884 for (c = 2; c < 6; ++c) if (coneCell[c] == f) break; 4885 if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 4886 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 4887 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (fornt[c-2] < 0 ? 1-r : r))%4; 4888 } 4889 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4890 #if 1 4891 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 4892 for (p = 0; p < size; ++p) { 4893 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); 4894 } 4895 #endif 4896 } 4897 } 4898 /* Hybrid cell faces have 4 edges and 2 cells */ 4899 for (c = cMax; c < cEnd; ++c) { 4900 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4; 4901 const PetscInt *cone, *ornt; 4902 PetscInt coneNew[4], orntNew[4]; 4903 PetscInt supportNew[2]; 4904 4905 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4906 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4907 for (r = 0; r < 4; ++r) { 4908 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r); 4909 orntNew[0] = 0; 4910 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r); 4911 orntNew[1] = 0; 4912 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax); 4913 orntNew[2] = 0; 4914 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 4915 orntNew[3] = 0; 4916 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4917 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4918 #if 1 4919 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); 4920 for (p = 0; p < 2; ++p) { 4921 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); 4922 } 4923 for (p = 2; p < 4; ++p) { 4924 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); 4925 } 4926 #endif 4927 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r); 4928 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4); 4929 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 4930 #if 1 4931 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); 4932 for (p = 0; p < 2; ++p) { 4933 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); 4934 } 4935 #endif 4936 } 4937 } 4938 /* Interior split edges have 2 vertices and the same faces as the parent */ 4939 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4940 for (e = eStart; e < eMax; ++e) { 4941 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4942 4943 for (r = 0; r < 2; ++r) { 4944 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4945 const PetscInt *cone, *ornt, *support; 4946 PetscInt coneNew[2], coneSize, c, supportSize, s; 4947 4948 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4949 coneNew[0] = vStartNew + (cone[0] - vStart); 4950 coneNew[1] = vStartNew + (cone[1] - vStart); 4951 coneNew[(r+1)%2] = newv; 4952 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4953 #if 1 4954 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4955 for (p = 0; p < 2; ++p) { 4956 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); 4957 } 4958 #endif 4959 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4960 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4961 for (s = 0; s < supportSize; ++s) { 4962 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4963 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4964 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4965 for (c = 0; c < coneSize; ++c) { 4966 if (cone[c] == e) break; 4967 } 4968 if (support[s] < fMax) { 4969 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4; 4970 } else { 4971 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 4972 } 4973 } 4974 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4975 #if 1 4976 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4977 for (p = 0; p < supportSize; ++p) { 4978 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); 4979 } 4980 #endif 4981 } 4982 } 4983 /* Interior face edges have 2 vertices and 2+cells faces */ 4984 for (f = fStart; f < fMax; ++f) { 4985 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}; 4986 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 4987 const PetscInt *cone, *coneCell, *orntCell, *support; 4988 PetscInt coneNew[2], coneSize, c, supportSize, s; 4989 4990 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4991 for (r = 0; r < 4; ++r) { 4992 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 4993 4994 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 4995 coneNew[1] = newv; 4996 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4997 #if 1 4998 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4999 for (p = 0; p < 2; ++p) { 5000 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); 5001 } 5002 #endif 5003 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5004 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5005 supportRef[0] = fStartNew + (f - fStart)*4 + r; 5006 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 5007 for (s = 0; s < supportSize; ++s) { 5008 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5009 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 5010 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 5011 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 5012 if (support[s] < cMax) { 5013 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 5014 } else { 5015 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + GetQuadEdgeInverse_Static(orntCell[c], r); 5016 } 5017 } 5018 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5019 #if 1 5020 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5021 for (p = 0; p < 2+supportSize; ++p) { 5022 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); 5023 } 5024 #endif 5025 } 5026 } 5027 /* Interior cell edges have 2 vertices and 4 faces */ 5028 for (c = cStart; c < cMax; ++c) { 5029 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}; 5030 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 5031 const PetscInt *cone; 5032 PetscInt coneNew[2], supportNew[4]; 5033 5034 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5035 for (r = 0; r < 6; ++r) { 5036 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 5037 5038 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 5039 coneNew[1] = newv; 5040 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5041 #if 1 5042 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5043 for (p = 0; p < 2; ++p) { 5044 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); 5045 } 5046 #endif 5047 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 5048 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5049 #if 1 5050 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5051 for (p = 0; p < 4; ++p) { 5052 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); 5053 } 5054 #endif 5055 } 5056 } 5057 /* Hybrid edges have two vertices and the same faces */ 5058 for (e = eMax; e < eEnd; ++e) { 5059 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 5060 const PetscInt *cone, *support, *fcone; 5061 PetscInt coneNew[2], size, fsize, s; 5062 5063 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5064 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5065 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5066 coneNew[0] = vStartNew + (cone[0] - vStart); 5067 coneNew[1] = vStartNew + (cone[1] - vStart); 5068 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5069 #if 1 5070 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5071 for (p = 0; p < 2; ++p) { 5072 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); 5073 } 5074 #endif 5075 for (s = 0; s < size; ++s) { 5076 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 5077 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 5078 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 5079 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 5080 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2; 5081 } 5082 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5083 #if 1 5084 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5085 for (p = 0; p < size; ++p) { 5086 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); 5087 } 5088 #endif 5089 } 5090 /* Hybrid face edges have 2 vertices and 2+cells faces */ 5091 for (f = fMax; f < fEnd; ++f) { 5092 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 5093 const PetscInt *cone, *support, *ccone, *cornt; 5094 PetscInt coneNew[2], size, csize, s; 5095 5096 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5097 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5098 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5099 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 5100 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 5101 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5102 #if 1 5103 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5104 for (p = 0; p < 2; ++p) { 5105 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); 5106 } 5107 #endif 5108 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0; 5109 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1; 5110 for (s = 0; s < size; ++s) { 5111 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 5112 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 5113 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 5114 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 5115 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]); 5116 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + GetQuadSubfaceInverse_Static(cornt[0], c-2); 5117 } 5118 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5119 #if 1 5120 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5121 for (p = 0; p < 2+size; ++p) { 5122 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); 5123 } 5124 #endif 5125 } 5126 /* Hybrid cell edges have 2 vertices and 4 faces */ 5127 for (c = cMax; c < cEnd; ++c) { 5128 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 5129 const PetscInt *cone, *support; 5130 PetscInt coneNew[2], size; 5131 5132 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5133 ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr); 5134 ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr); 5135 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 5136 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 5137 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5138 #if 1 5139 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5140 for (p = 0; p < 2; ++p) { 5141 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); 5142 } 5143 #endif 5144 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0; 5145 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1; 5146 supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2; 5147 supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3; 5148 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5149 #if 1 5150 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5151 for (p = 0; p < 4; ++p) { 5152 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); 5153 } 5154 #endif 5155 } 5156 /* Interior vertices have identical supports */ 5157 for (v = vStart; v < vEnd; ++v) { 5158 const PetscInt newp = vStartNew + (v - vStart); 5159 const PetscInt *support, *cone; 5160 PetscInt size, s; 5161 5162 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 5163 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 5164 for (s = 0; s < size; ++s) { 5165 PetscInt r = 0; 5166 5167 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5168 if (cone[1] == v) r = 1; 5169 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 5170 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax); 5171 } 5172 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5173 #if 1 5174 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5175 for (p = 0; p < size; ++p) { 5176 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); 5177 } 5178 #endif 5179 } 5180 /* Interior edge vertices have 2 + faces supports */ 5181 for (e = eStart; e < eMax; ++e) { 5182 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 5183 const PetscInt *cone, *support; 5184 PetscInt size, s; 5185 5186 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5187 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5188 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 5189 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 5190 for (s = 0; s < size; ++s) { 5191 PetscInt r; 5192 5193 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5194 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 5195 if (support[s] < fMax) { 5196 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r; 5197 } else { 5198 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax); 5199 } 5200 } 5201 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5202 #if 1 5203 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5204 for (p = 0; p < 2+size; ++p) { 5205 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); 5206 } 5207 #endif 5208 } 5209 /* Interior face vertices have 4 + cells supports */ 5210 for (f = fStart; f < fMax; ++f) { 5211 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5212 const PetscInt *cone, *support; 5213 PetscInt size, s; 5214 5215 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5216 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5217 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 5218 for (s = 0; s < size; ++s) { 5219 PetscInt r; 5220 5221 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5222 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 5223 if (support[s] < cMax) { 5224 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r; 5225 } else { 5226 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax); 5227 } 5228 } 5229 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5230 #if 1 5231 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5232 for (p = 0; p < 4+size; ++p) { 5233 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); 5234 } 5235 #endif 5236 } 5237 /* Cell vertices have 6 supports */ 5238 for (c = cStart; c < cMax; ++c) { 5239 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 5240 PetscInt supportNew[6]; 5241 5242 for (r = 0; r < 6; ++r) { 5243 supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 5244 } 5245 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5246 } 5247 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5248 break; 5249 default: 5250 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5251 } 5252 PetscFunctionReturn(0); 5253 } 5254 5255 #undef __FUNCT__ 5256 #define __FUNCT__ "CellRefinerSetCoordinates" 5257 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5258 { 5259 PetscSection coordSection, coordSectionNew; 5260 Vec coordinates, coordinatesNew; 5261 PetscScalar *coords, *coordsNew; 5262 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 5263 PetscInt dim, depth, coordSizeNew, cStart, cEnd, cMax, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 5264 PetscErrorCode ierr; 5265 5266 PetscFunctionBegin; 5267 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 5268 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5269 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5270 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5271 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5272 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5273 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 5274 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);} 5275 ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr); 5276 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 5277 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 5278 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 5279 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dim);CHKERRQ(ierr); 5280 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 5281 if (cMax < 0) cMax = cEnd; 5282 if (fMax < 0) fMax = fEnd; 5283 if (eMax < 0) eMax = eEnd; 5284 /* All vertices have the dim coordinates */ 5285 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 5286 ierr = PetscSectionSetDof(coordSectionNew, v, dim);CHKERRQ(ierr); 5287 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dim);CHKERRQ(ierr); 5288 } 5289 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 5290 ierr = DMSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr); 5291 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 5292 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 5293 ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr); 5294 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 5295 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 5296 ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr); 5297 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 5298 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 5299 switch (refiner) { 5300 case 0: break; 5301 case 6: /* Hex 3D */ 5302 case 8: /* Hybrid Hex 3D */ 5303 /* Face vertices have the average of corner coordinates */ 5304 for (f = fStart; f < fMax; ++f) { 5305 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5306 PetscInt *cone = NULL; 5307 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 5308 5309 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5310 for (p = 0; p < closureSize*2; p += 2) { 5311 const PetscInt point = cone[p]; 5312 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 5313 } 5314 for (v = 0; v < coneSize; ++v) { 5315 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 5316 } 5317 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5318 for (d = 0; d < dim; ++d) { 5319 coordsNew[offnew+d] = 0.0; 5320 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 5321 coordsNew[offnew+d] /= coneSize; 5322 } 5323 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5324 } 5325 case 2: /* Hex 2D */ 5326 case 4: /* Hybrid Hex 2D */ 5327 /* Cell vertices have the average of corner coordinates */ 5328 for (c = cStart; c < cMax; ++c) { 5329 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0); 5330 PetscInt *cone = NULL; 5331 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 5332 5333 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5334 for (p = 0; p < closureSize*2; p += 2) { 5335 const PetscInt point = cone[p]; 5336 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 5337 } 5338 for (v = 0; v < coneSize; ++v) { 5339 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 5340 } 5341 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5342 for (d = 0; d < dim; ++d) { 5343 coordsNew[offnew+d] = 0.0; 5344 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 5345 coordsNew[offnew+d] /= coneSize; 5346 } 5347 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5348 } 5349 case 1: /* Simplicial 2D */ 5350 case 3: /* Hybrid Simplicial 2D */ 5351 case 5: /* Simplicial 3D */ 5352 case 7: /* Hybrid Simplicial 3D */ 5353 /* Edge vertices have the average of endpoint coordinates */ 5354 for (e = eStart; e < eMax; ++e) { 5355 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5356 const PetscInt *cone; 5357 PetscInt coneSize, offA, offB, offnew, d; 5358 5359 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 5360 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 5361 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5362 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 5363 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 5364 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5365 for (d = 0; d < dim; ++d) { 5366 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]); 5367 } 5368 } 5369 /* Old vertices have the same coordinates */ 5370 for (v = vStart; v < vEnd; ++v) { 5371 const PetscInt newv = vStartNew + (v - vStart); 5372 PetscInt off, offnew, d; 5373 5374 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 5375 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5376 for (d = 0; d < dim; ++d) { 5377 coordsNew[offnew+d] = coords[off+d]; 5378 } 5379 } 5380 break; 5381 default: 5382 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5383 } 5384 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 5385 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 5386 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 5387 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 5388 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 5389 PetscFunctionReturn(0); 5390 } 5391 5392 #undef __FUNCT__ 5393 #define __FUNCT__ "DMPlexCreateProcessSF" 5394 static PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 5395 { 5396 PetscInt numRoots, numLeaves, l; 5397 const PetscInt *localPoints; 5398 const PetscSFNode *remotePoints; 5399 PetscInt *localPointsNew; 5400 PetscSFNode *remotePointsNew; 5401 PetscInt *ranks, *ranksNew; 5402 PetscErrorCode ierr; 5403 5404 PetscFunctionBegin; 5405 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5406 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 5407 for (l = 0; l < numLeaves; ++l) { 5408 ranks[l] = remotePoints[l].rank; 5409 } 5410 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 5411 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 5412 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 5413 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 5414 for (l = 0; l < numLeaves; ++l) { 5415 ranksNew[l] = ranks[l]; 5416 localPointsNew[l] = l; 5417 remotePointsNew[l].index = 0; 5418 remotePointsNew[l].rank = ranksNew[l]; 5419 } 5420 ierr = PetscFree(ranks);CHKERRQ(ierr); 5421 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr); 5422 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 5423 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 5424 ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 5425 PetscFunctionReturn(0); 5426 } 5427 5428 #undef __FUNCT__ 5429 #define __FUNCT__ "CellRefinerCreateSF" 5430 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5431 { 5432 PetscSF sf, sfNew, sfProcess; 5433 IS processRanks; 5434 MPI_Datatype depthType; 5435 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 5436 const PetscInt *localPoints, *neighbors; 5437 const PetscSFNode *remotePoints; 5438 PetscInt *localPointsNew; 5439 PetscSFNode *remotePointsNew; 5440 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 5441 PetscInt depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 5442 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 5443 PetscErrorCode ierr; 5444 5445 PetscFunctionBegin; 5446 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 5447 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5448 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5449 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5450 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5451 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5452 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 5453 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 5454 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 5455 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 5456 /* Caculate size of new SF */ 5457 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5458 if (numRoots < 0) PetscFunctionReturn(0); 5459 for (l = 0; l < numLeaves; ++l) { 5460 const PetscInt p = localPoints[l]; 5461 5462 switch (refiner) { 5463 case 1: 5464 /* Simplicial 2D */ 5465 if ((p >= vStart) && (p < vEnd)) { 5466 /* Old vertices stay the same */ 5467 ++numLeavesNew; 5468 } else if ((p >= fStart) && (p < fEnd)) { 5469 /* Old faces add new faces and vertex */ 5470 numLeavesNew += 2 + 1; 5471 } else if ((p >= cStart) && (p < cEnd)) { 5472 /* Old cells add new cells and interior faces */ 5473 numLeavesNew += 4 + 3; 5474 } 5475 break; 5476 case 3: 5477 /* Hybrid Simplicial 2D */ 5478 if ((p >= vStart) && (p < vEnd)) { 5479 /* Interior vertices stay the same */ 5480 ++numLeavesNew; 5481 } else if ((p >= fStart) && (p < fMax)) { 5482 /* Interior faces add new faces and vertex */ 5483 numLeavesNew += 2 + 1; 5484 } else if ((p >= fMax) && (p < fEnd)) { 5485 /* Hybrid faces stay the same */ 5486 ++numLeavesNew; 5487 } else if ((p >= cStart) && (p < cMax)) { 5488 /* Interior cells add new cells and interior faces */ 5489 numLeavesNew += 4 + 3; 5490 } else if ((p >= cMax) && (p < cEnd)) { 5491 /* Hybrid cells add new cells and hybrid face */ 5492 numLeavesNew += 2 + 1; 5493 } 5494 break; 5495 case 2: 5496 /* Hex 2D */ 5497 if ((p >= vStart) && (p < vEnd)) { 5498 /* Old vertices stay the same */ 5499 ++numLeavesNew; 5500 } else if ((p >= fStart) && (p < fEnd)) { 5501 /* Old faces add new faces and vertex */ 5502 numLeavesNew += 2 + 1; 5503 } else if ((p >= cStart) && (p < cEnd)) { 5504 /* Old cells add new cells, interior faces, and vertex */ 5505 numLeavesNew += 4 + 4 + 1; 5506 } 5507 break; 5508 case 4: 5509 /* Hybrid Hex 2D */ 5510 if ((p >= vStart) && (p < vEnd)) { 5511 /* Interior vertices stay the same */ 5512 ++numLeavesNew; 5513 } else if ((p >= fStart) && (p < fMax)) { 5514 /* Interior faces add new faces and vertex */ 5515 numLeavesNew += 2 + 1; 5516 } else if ((p >= fMax) && (p < fEnd)) { 5517 /* Hybrid faces stay the same */ 5518 ++numLeavesNew; 5519 } else if ((p >= cStart) && (p < cMax)) { 5520 /* Interior cells add new cells, interior faces, and vertex */ 5521 numLeavesNew += 4 + 4 + 1; 5522 } else if ((p >= cMax) && (p < cEnd)) { 5523 /* Hybrid cells add new cells and hybrid face */ 5524 numLeavesNew += 2 + 1; 5525 } 5526 break; 5527 case 5: 5528 /* Simplicial 3D */ 5529 if ((p >= vStart) && (p < vEnd)) { 5530 /* Old vertices stay the same */ 5531 ++numLeavesNew; 5532 } else if ((p >= eStart) && (p < eEnd)) { 5533 /* Old edges add new edges and vertex */ 5534 numLeavesNew += 2 + 1; 5535 } else if ((p >= fStart) && (p < fEnd)) { 5536 /* Old faces add new faces and face edges */ 5537 numLeavesNew += 4 + 3; 5538 } else if ((p >= cStart) && (p < cEnd)) { 5539 /* Old cells add new cells and interior faces and edges */ 5540 numLeavesNew += 8 + 8 + 1; 5541 } 5542 break; 5543 case 7: 5544 /* Hybrid Simplicial 3D */ 5545 if ((p >= vStart) && (p < vEnd)) { 5546 /* Interior vertices stay the same */ 5547 ++numLeavesNew; 5548 } else if ((p >= eStart) && (p < eMax)) { 5549 /* Interior edges add new edges and vertex */ 5550 numLeavesNew += 2 + 1; 5551 } else if ((p >= eMax) && (p < eEnd)) { 5552 /* Hybrid edges stay the same */ 5553 ++numLeavesNew; 5554 } else if ((p >= fStart) && (p < fMax)) { 5555 /* Interior faces add new faces and edges */ 5556 numLeavesNew += 4 + 3; 5557 } else if ((p >= fMax) && (p < fEnd)) { 5558 /* Hybrid faces add new faces and edges */ 5559 numLeavesNew += 2 + 1; 5560 } else if ((p >= cStart) && (p < cMax)) { 5561 /* Interior cells add new cells, faces, and edges */ 5562 numLeavesNew += 8 + 8 + 1; 5563 } else if ((p >= cMax) && (p < cEnd)) { 5564 /* Hybrid cells add new cells and faces */ 5565 numLeavesNew += 4 + 3; 5566 } 5567 break; 5568 case 6: 5569 /* Hex 3D */ 5570 if ((p >= vStart) && (p < vEnd)) { 5571 /* Old vertices stay the same */ 5572 ++numLeavesNew; 5573 } else if ((p >= eStart) && (p < eEnd)) { 5574 /* Old edges add new edges, and vertex */ 5575 numLeavesNew += 2 + 1; 5576 } else if ((p >= fStart) && (p < fEnd)) { 5577 /* Old faces add new faces, edges, and vertex */ 5578 numLeavesNew += 4 + 4 + 1; 5579 } else if ((p >= cStart) && (p < cEnd)) { 5580 /* Old cells add new cells, faces, edges, and vertex */ 5581 numLeavesNew += 8 + 12 + 6 + 1; 5582 } 5583 break; 5584 case 8: 5585 /* Hybrid Hex 3D */ 5586 if ((p >= vStart) && (p < vEnd)) { 5587 /* Old vertices stay the same */ 5588 ++numLeavesNew; 5589 } else if ((p >= eStart) && (p < eMax)) { 5590 /* Interior edges add new edges, and vertex */ 5591 numLeavesNew += 2 + 1; 5592 } else if ((p >= eMax) && (p < eEnd)) { 5593 /* Hybrid edges stay the same */ 5594 ++numLeavesNew; 5595 } else if ((p >= fStart) && (p < fMax)) { 5596 /* Interior faces add new faces, edges, and vertex */ 5597 numLeavesNew += 4 + 4 + 1; 5598 } else if ((p >= fMax) && (p < fEnd)) { 5599 /* Hybrid faces add new faces and edges */ 5600 numLeavesNew += 2 + 1; 5601 } else if ((p >= cStart) && (p < cMax)) { 5602 /* Interior cells add new cells, faces, edges, and vertex */ 5603 numLeavesNew += 8 + 12 + 6 + 1; 5604 } else if ((p >= cStart) && (p < cEnd)) { 5605 /* Hybrid cells add new cells, faces, and edges */ 5606 numLeavesNew += 4 + 4 + 1; 5607 } 5608 break; 5609 default: 5610 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5611 } 5612 } 5613 /* Communicate depthSizes for each remote rank */ 5614 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 5615 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 5616 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 5617 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 5618 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 5619 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 5620 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5621 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5622 for (n = 0; n < numNeighbors; ++n) { 5623 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 5624 } 5625 depthSizeOld[depth] = cMax; 5626 depthSizeOld[0] = vMax; 5627 depthSizeOld[depth-1] = fMax; 5628 depthSizeOld[1] = eMax; 5629 5630 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5631 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5632 5633 depthSizeOld[depth] = cEnd - cStart; 5634 depthSizeOld[0] = vEnd - vStart; 5635 depthSizeOld[depth-1] = fEnd - fStart; 5636 depthSizeOld[1] = eEnd - eStart; 5637 5638 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5639 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5640 for (n = 0; n < numNeighbors; ++n) { 5641 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 5642 } 5643 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 5644 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 5645 /* Calculate new point SF */ 5646 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 5647 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 5648 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 5649 for (l = 0, m = 0; l < numLeaves; ++l) { 5650 PetscInt p = localPoints[l]; 5651 PetscInt rp = remotePoints[l].index, n; 5652 PetscMPIInt rrank = remotePoints[l].rank; 5653 5654 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 5655 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 5656 switch (refiner) { 5657 case 1: 5658 /* Simplicial 2D */ 5659 if ((p >= vStart) && (p < vEnd)) { 5660 /* Old vertices stay the same */ 5661 localPointsNew[m] = vStartNew + (p - vStart); 5662 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5663 remotePointsNew[m].rank = rrank; 5664 ++m; 5665 } else if ((p >= fStart) && (p < fEnd)) { 5666 /* Old faces add new faces and vertex */ 5667 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5668 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5669 remotePointsNew[m].rank = rrank; 5670 ++m; 5671 for (r = 0; r < 2; ++r, ++m) { 5672 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5673 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5674 remotePointsNew[m].rank = rrank; 5675 } 5676 } else if ((p >= cStart) && (p < cEnd)) { 5677 /* Old cells add new cells and interior faces */ 5678 for (r = 0; r < 4; ++r, ++m) { 5679 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5680 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5681 remotePointsNew[m].rank = rrank; 5682 } 5683 for (r = 0; r < 3; ++r, ++m) { 5684 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 5685 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 5686 remotePointsNew[m].rank = rrank; 5687 } 5688 } 5689 break; 5690 case 2: 5691 /* Hex 2D */ 5692 if ((p >= vStart) && (p < vEnd)) { 5693 /* Old vertices stay the same */ 5694 localPointsNew[m] = vStartNew + (p - vStart); 5695 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5696 remotePointsNew[m].rank = rrank; 5697 ++m; 5698 } else if ((p >= fStart) && (p < fEnd)) { 5699 /* Old faces add new faces and vertex */ 5700 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5701 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5702 remotePointsNew[m].rank = rrank; 5703 ++m; 5704 for (r = 0; r < 2; ++r, ++m) { 5705 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5706 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5707 remotePointsNew[m].rank = rrank; 5708 } 5709 } else if ((p >= cStart) && (p < cEnd)) { 5710 /* Old cells add new cells, interior faces, and vertex */ 5711 for (r = 0; r < 4; ++r, ++m) { 5712 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5713 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5714 remotePointsNew[m].rank = rrank; 5715 } 5716 for (r = 0; r < 4; ++r, ++m) { 5717 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 5718 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r; 5719 remotePointsNew[m].rank = rrank; 5720 } 5721 for (r = 0; r < 1; ++r, ++m) { 5722 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart) + r; 5723 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 5724 remotePointsNew[m].rank = rrank; 5725 } 5726 } 5727 break; 5728 case 3: 5729 /* Hybrid simplicial 2D */ 5730 if ((p >= vStart) && (p < vEnd)) { 5731 /* Old vertices stay the same */ 5732 localPointsNew[m] = vStartNew + (p - vStart); 5733 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5734 remotePointsNew[m].rank = rrank; 5735 ++m; 5736 } else if ((p >= fStart) && (p < fMax)) { 5737 /* Old interior faces add new faces and vertex */ 5738 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5739 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5740 remotePointsNew[m].rank = rrank; 5741 ++m; 5742 for (r = 0; r < 2; ++r, ++m) { 5743 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5744 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5745 remotePointsNew[m].rank = rrank; 5746 } 5747 } else if ((p >= fMax) && (p < fEnd)) { 5748 /* Old hybrid faces stay the same */ 5749 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 5750 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5751 remotePointsNew[m].rank = rrank; 5752 ++m; 5753 } else if ((p >= cStart) && (p < cMax)) { 5754 /* Old interior cells add new cells and interior faces */ 5755 for (r = 0; r < 4; ++r, ++m) { 5756 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5757 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5758 remotePointsNew[m].rank = rrank; 5759 } 5760 for (r = 0; r < 3; ++r, ++m) { 5761 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 5762 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 5763 remotePointsNew[m].rank = rrank; 5764 } 5765 } else if ((p >= cStart) && (p < cMax)) { 5766 /* Old hybrid cells add new cells and hybrid face */ 5767 for (r = 0; r < 2; ++r, ++m) { 5768 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5769 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5770 remotePointsNew[m].rank = rrank; 5771 } 5772 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 5773 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]); 5774 remotePointsNew[m].rank = rrank; 5775 ++m; 5776 } 5777 break; 5778 case 4: 5779 /* Hybrid Hex 2D */ 5780 if ((p >= vStart) && (p < vEnd)) { 5781 /* Old vertices stay the same */ 5782 localPointsNew[m] = vStartNew + (p - vStart); 5783 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5784 remotePointsNew[m].rank = rrank; 5785 ++m; 5786 } else if ((p >= fStart) && (p < fMax)) { 5787 /* Old interior faces add new faces and vertex */ 5788 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5789 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5790 remotePointsNew[m].rank = rrank; 5791 ++m; 5792 for (r = 0; r < 2; ++r, ++m) { 5793 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5794 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5795 remotePointsNew[m].rank = rrank; 5796 } 5797 } else if ((p >= fMax) && (p < fEnd)) { 5798 /* Old hybrid faces stay the same */ 5799 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 5800 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5801 remotePointsNew[m].rank = rrank; 5802 ++m; 5803 } else if ((p >= cStart) && (p < cMax)) { 5804 /* Old interior cells add new cells, interior faces, and vertex */ 5805 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 5806 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 5807 remotePointsNew[m].rank = rrank; 5808 ++m; 5809 for (r = 0; r < 4; ++r, ++m) { 5810 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5811 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5812 remotePointsNew[m].rank = rrank; 5813 } 5814 for (r = 0; r < 4; ++r, ++m) { 5815 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r; 5816 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r; 5817 remotePointsNew[m].rank = rrank; 5818 } 5819 } else if ((p >= cStart) && (p < cMax)) { 5820 /* Old hybrid cells add new cells and hybrid face */ 5821 for (r = 0; r < 2; ++r, ++m) { 5822 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5823 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5824 remotePointsNew[m].rank = rrank; 5825 } 5826 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 5827 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*4 + (rp - rdepthMaxOld[n*(depth+1)+depth]); 5828 remotePointsNew[m].rank = rrank; 5829 ++m; 5830 } 5831 break; 5832 case 5: 5833 /* Simplicial 3D */ 5834 if ((p >= vStart) && (p < vEnd)) { 5835 /* Old vertices stay the same */ 5836 localPointsNew[m] = vStartNew + (p - vStart); 5837 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5838 remotePointsNew[m].rank = rrank; 5839 ++m; 5840 } else if ((p >= eStart) && (p < eEnd)) { 5841 /* Old edges add new edges and vertex */ 5842 for (r = 0; r < 2; ++r, ++m) { 5843 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5844 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5845 remotePointsNew[m].rank = rrank; 5846 } 5847 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5848 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5849 remotePointsNew[m].rank = rrank; 5850 ++m; 5851 } else if ((p >= fStart) && (p < fEnd)) { 5852 /* Old faces add new faces and face edges */ 5853 for (r = 0; r < 4; ++r, ++m) { 5854 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5855 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5856 remotePointsNew[m].rank = rrank; 5857 } 5858 for (r = 0; r < 3; ++r, ++m) { 5859 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 5860 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*3 + r; 5861 remotePointsNew[m].rank = rrank; 5862 } 5863 } else if ((p >= cStart) && (p < cEnd)) { 5864 /* Old cells add new cells and interior faces and edges */ 5865 for (r = 0; r < 8; ++r, ++m) { 5866 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 5867 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 5868 remotePointsNew[m].rank = rrank; 5869 } 5870 for (r = 0; r < 8; ++r, ++m) { 5871 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 5872 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*8 + r; 5873 remotePointsNew[m].rank = rrank; 5874 } 5875 for (r = 0; r < 1; ++r, ++m) { 5876 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 5877 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*1 + r; 5878 remotePointsNew[m].rank = rrank; 5879 } 5880 } 5881 break; 5882 case 7: 5883 /* Hybrid Simplicial 3D */ 5884 if ((p >= vStart) && (p < vEnd)) { 5885 /* Interior vertices stay the same */ 5886 localPointsNew[m] = vStartNew + (p - vStart); 5887 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5888 remotePointsNew[m].rank = rrank; 5889 ++m; 5890 } else if ((p >= eStart) && (p < eMax)) { 5891 /* Interior edges add new edges and vertex */ 5892 for (r = 0; r < 2; ++r, ++m) { 5893 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5894 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5895 remotePointsNew[m].rank = rrank; 5896 } 5897 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5898 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5899 remotePointsNew[m].rank = rrank; 5900 ++m; 5901 } else if ((p >= eMax) && (p < eEnd)) { 5902 /* Hybrid edges stay the same */ 5903 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 5904 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]); 5905 remotePointsNew[m].rank = rrank; 5906 ++m; 5907 } else if ((p >= fStart) && (p < fMax)) { 5908 /* Interior faces add new faces and edges */ 5909 for (r = 0; r < 4; ++r, ++m) { 5910 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5911 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5912 remotePointsNew[m].rank = rrank; 5913 } 5914 for (r = 0; r < 3; ++r, ++m) { 5915 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 5916 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 5917 remotePointsNew[m].rank = rrank; 5918 } 5919 } else if ((p >= fMax) && (p < fEnd)) { 5920 /* Hybrid faces add new faces and edges */ 5921 for (r = 0; r < 2; ++r, ++m) { 5922 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 5923 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth-1])*2 + r; 5924 remotePointsNew[m].rank = rrank; 5925 } 5926 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 5927 remotePointsNew[m].index = reStartNew[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)+depth-1]); 5928 remotePointsNew[m].rank = rrank; 5929 ++m; 5930 } else if ((p >= cStart) && (p < cMax)) { 5931 /* Interior cells add new cells, faces, and edges */ 5932 for (r = 0; r < 8; ++r, ++m) { 5933 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 5934 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 5935 remotePointsNew[m].rank = rrank; 5936 } 5937 for (r = 0; r < 8; ++r, ++m) { 5938 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 5939 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 5940 remotePointsNew[m].rank = rrank; 5941 } 5942 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + r; 5943 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; 5944 remotePointsNew[m].rank = rrank; 5945 ++m; 5946 } else if ((p >= cMax) && (p < cEnd)) { 5947 /* Hybrid cells add new cells and faces */ 5948 for (r = 0; r < 4; ++r, ++m) { 5949 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 5950 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 5951 remotePointsNew[m].rank = rrank; 5952 } 5953 for (r = 0; r < 3; ++r, ++m) { 5954 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 5955 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])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth])*3 + r; 5956 remotePointsNew[m].rank = rrank; 5957 } 5958 } 5959 break; 5960 case 6: 5961 /* Hex 3D */ 5962 if ((p >= vStart) && (p < vEnd)) { 5963 /* Old vertices stay the same */ 5964 localPointsNew[m] = vStartNew + (p - vStart); 5965 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5966 remotePointsNew[m].rank = rrank; 5967 ++m; 5968 } else if ((p >= eStart) && (p < eEnd)) { 5969 /* Old edges add new edges and vertex */ 5970 for (r = 0; r < 2; ++r, ++m) { 5971 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5972 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5973 remotePointsNew[m].rank = rrank; 5974 } 5975 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5976 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5977 remotePointsNew[m].rank = rrank; 5978 ++m; 5979 } else if ((p >= fStart) && (p < fEnd)) { 5980 /* Old faces add new faces, edges, and vertex */ 5981 for (r = 0; r < 4; ++r, ++m) { 5982 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5983 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5984 remotePointsNew[m].rank = rrank; 5985 } 5986 for (r = 0; r < 4; ++r, ++m) { 5987 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 5988 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*4 + r; 5989 remotePointsNew[m].rank = rrank; 5990 } 5991 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 5992 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]); 5993 remotePointsNew[m].rank = rrank; 5994 ++m; 5995 } else if ((p >= cStart) && (p < cEnd)) { 5996 /* Old cells add new cells, faces, edges, and vertex */ 5997 for (r = 0; r < 8; ++r, ++m) { 5998 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 5999 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 6000 remotePointsNew[m].rank = rrank; 6001 } 6002 for (r = 0; r < 12; ++r, ++m) { 6003 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 6004 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*12 + r; 6005 remotePointsNew[m].rank = rrank; 6006 } 6007 for (r = 0; r < 6; ++r, ++m) { 6008 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 6009 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*6 + r; 6010 remotePointsNew[m].rank = rrank; 6011 } 6012 for (r = 0; r < 1; ++r, ++m) { 6013 localPointsNew[m] = vStartNew + (eEnd - eStart) + (fEnd - fStart) + (p - cStart) + r; 6014 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 6015 remotePointsNew[m].rank = rrank; 6016 } 6017 } 6018 break; 6019 case 8: 6020 /* Hybrid Hex 3D */ 6021 if ((p >= vStart) && (p < vEnd)) { 6022 /* Interior vertices stay the same */ 6023 localPointsNew[m] = vStartNew + (p - vStart); 6024 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 6025 remotePointsNew[m].rank = rrank; 6026 ++m; 6027 } else if ((p >= eStart) && (p < eMax)) { 6028 /* Interior edges add new edges and vertex */ 6029 for (r = 0; r < 2; ++r, ++m) { 6030 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 6031 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 6032 remotePointsNew[m].rank = rrank; 6033 } 6034 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 6035 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 6036 remotePointsNew[m].rank = rrank; 6037 ++m; 6038 } else if ((p >= eMax) && (p < eEnd)) { 6039 /* Hybrid edges stay the same */ 6040 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 6041 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rp - rdepthMaxOld[n*(depth+1)+1]); 6042 remotePointsNew[m].rank = rrank; 6043 ++m; 6044 } else if ((p >= fStart) && (p < fMax)) { 6045 /* Interior faces add new faces, edges, and vertex */ 6046 for (r = 0; r < 4; ++r, ++m) { 6047 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 6048 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 6049 remotePointsNew[m].rank = rrank; 6050 } 6051 for (r = 0; r < 4; ++r, ++m) { 6052 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 6053 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 6054 remotePointsNew[m].rank = rrank; 6055 } 6056 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 6057 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 6058 remotePointsNew[m].rank = rrank; 6059 ++m; 6060 } else if ((p >= fMax) && (p < fEnd)) { 6061 /* Hybrid faces add new faces and edges */ 6062 for (r = 0; r < 2; ++r, ++m) { 6063 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 6064 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth-1])*2 + r; 6065 remotePointsNew[m].rank = rrank; 6066 } 6067 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax); 6068 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1]); 6069 remotePointsNew[m].rank = rrank; 6070 ++m; 6071 } else if ((p >= cStart) && (p < cMax)) { 6072 /* Interior cells add new cells, faces, edges, and vertex */ 6073 for (r = 0; r < 8; ++r, ++m) { 6074 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 6075 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 6076 remotePointsNew[m].rank = rrank; 6077 } 6078 for (r = 0; r < 12; ++r, ++m) { 6079 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 6080 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 6081 remotePointsNew[m].rank = rrank; 6082 } 6083 for (r = 0; r < 6; ++r, ++m) { 6084 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 6085 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*6 + r; 6086 remotePointsNew[m].rank = rrank; 6087 } 6088 for (r = 0; r < 1; ++r, ++m) { 6089 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 6090 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 6091 remotePointsNew[m].rank = rrank; 6092 } 6093 } else if ((p >= cMax) && (p < cEnd)) { 6094 /* Hybrid cells add new cells, faces, and edges */ 6095 for (r = 0; r < 4; ++r, ++m) { 6096 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6097 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 6098 remotePointsNew[m].rank = rrank; 6099 } 6100 for (r = 0; r < 4; ++r, ++m) { 6101 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 6102 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])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 6103 remotePointsNew[m].rank = rrank; 6104 } 6105 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 6106 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1]) + (rp - rdepthMaxOld[n*(depth+1)+depth]); 6107 remotePointsNew[m].rank = rrank; 6108 ++m; 6109 } 6110 break; 6111 default: 6112 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6113 } 6114 } 6115 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew); 6116 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 6117 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 6118 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 6119 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 6120 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 6121 PetscFunctionReturn(0); 6122 } 6123 6124 #undef __FUNCT__ 6125 #define __FUNCT__ "CellRefinerCreateLabels" 6126 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 6127 { 6128 PetscInt numLabels, l; 6129 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 6130 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 6131 PetscErrorCode ierr; 6132 6133 PetscFunctionBegin; 6134 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6135 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 6136 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6137 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 6138 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6139 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 6140 ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 6141 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 6142 switch (refiner) { 6143 case 0: break; 6144 case 7: 6145 case 8: 6146 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 6147 case 3: 6148 case 4: 6149 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 6150 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 6151 } 6152 for (l = 0; l < numLabels; ++l) { 6153 DMLabel label, labelNew; 6154 const char *lname; 6155 PetscBool isDepth; 6156 IS valueIS; 6157 const PetscInt *values; 6158 PetscInt numValues, val; 6159 6160 ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr); 6161 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 6162 if (isDepth) continue; 6163 ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr); 6164 ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr); 6165 ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 6166 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 6167 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 6168 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 6169 for (val = 0; val < numValues; ++val) { 6170 IS pointIS; 6171 const PetscInt *points; 6172 PetscInt numPoints, n; 6173 6174 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 6175 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 6176 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 6177 for (n = 0; n < numPoints; ++n) { 6178 const PetscInt p = points[n]; 6179 switch (refiner) { 6180 case 1: 6181 /* Simplicial 2D */ 6182 if ((p >= vStart) && (p < vEnd)) { 6183 /* Old vertices stay the same */ 6184 newp = vStartNew + (p - vStart); 6185 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6186 } else if ((p >= fStart) && (p < fEnd)) { 6187 /* Old faces add new faces and vertex */ 6188 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6189 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6190 for (r = 0; r < 2; ++r) { 6191 newp = fStartNew + (p - fStart)*2 + r; 6192 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6193 } 6194 } else if ((p >= cStart) && (p < cEnd)) { 6195 /* Old cells add new cells and interior faces */ 6196 for (r = 0; r < 4; ++r) { 6197 newp = cStartNew + (p - cStart)*4 + r; 6198 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6199 } 6200 for (r = 0; r < 3; ++r) { 6201 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 6202 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6203 } 6204 } 6205 break; 6206 case 2: 6207 /* Hex 2D */ 6208 if ((p >= vStart) && (p < vEnd)) { 6209 /* Old vertices stay the same */ 6210 newp = vStartNew + (p - vStart); 6211 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6212 } else if ((p >= fStart) && (p < fEnd)) { 6213 /* Old faces add new faces and vertex */ 6214 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6215 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6216 for (r = 0; r < 2; ++r) { 6217 newp = fStartNew + (p - fStart)*2 + r; 6218 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6219 } 6220 } else if ((p >= cStart) && (p < cEnd)) { 6221 /* Old cells add new cells and interior faces and vertex */ 6222 for (r = 0; r < 4; ++r) { 6223 newp = cStartNew + (p - cStart)*4 + r; 6224 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6225 } 6226 for (r = 0; r < 4; ++r) { 6227 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 6228 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6229 } 6230 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 6231 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6232 } 6233 break; 6234 case 3: 6235 /* Hybrid simplicial 2D */ 6236 if ((p >= vStart) && (p < vEnd)) { 6237 /* Old vertices stay the same */ 6238 newp = vStartNew + (p - vStart); 6239 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6240 } else if ((p >= fStart) && (p < fMax)) { 6241 /* Old interior faces add new faces and vertex */ 6242 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6243 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6244 for (r = 0; r < 2; ++r) { 6245 newp = fStartNew + (p - fStart)*2 + r; 6246 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6247 } 6248 } else if ((p >= fMax) && (p < fEnd)) { 6249 /* Old hybrid faces stay the same */ 6250 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 6251 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6252 } else if ((p >= cStart) && (p < cMax)) { 6253 /* Old interior cells add new cells and interior faces */ 6254 for (r = 0; r < 4; ++r) { 6255 newp = cStartNew + (p - cStart)*4 + r; 6256 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6257 } 6258 for (r = 0; r < 3; ++r) { 6259 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 6260 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6261 } 6262 } else if ((p >= cMax) && (p < cEnd)) { 6263 /* Old hybrid cells add new cells and hybrid face */ 6264 for (r = 0; r < 2; ++r) { 6265 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 6266 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6267 } 6268 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 6269 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6270 } 6271 break; 6272 case 4: 6273 /* Hybrid Hex 2D */ 6274 if ((p >= vStart) && (p < vEnd)) { 6275 /* Old vertices stay the same */ 6276 newp = vStartNew + (p - vStart); 6277 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6278 } else if ((p >= fStart) && (p < fMax)) { 6279 /* Old interior faces add new faces and vertex */ 6280 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6281 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6282 for (r = 0; r < 2; ++r) { 6283 newp = fStartNew + (p - fStart)*2 + r; 6284 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6285 } 6286 } else if ((p >= fMax) && (p < fEnd)) { 6287 /* Old hybrid faces stay the same */ 6288 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 6289 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6290 } else if ((p >= cStart) && (p < cMax)) { 6291 /* Old interior cells add new cells, interior faces, and vertex */ 6292 for (r = 0; r < 4; ++r) { 6293 newp = cStartNew + (p - cStart)*4 + r; 6294 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6295 } 6296 for (r = 0; r < 4; ++r) { 6297 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 6298 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6299 } 6300 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 6301 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6302 } else if ((p >= cMax) && (p < cEnd)) { 6303 /* Old hybrid cells add new cells and hybrid face */ 6304 for (r = 0; r < 2; ++r) { 6305 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 6306 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6307 } 6308 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 6309 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6310 } 6311 break; 6312 case 5: 6313 /* Simplicial 3D */ 6314 if ((p >= vStart) && (p < vEnd)) { 6315 /* Old vertices stay the same */ 6316 newp = vStartNew + (p - vStart); 6317 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6318 } else if ((p >= eStart) && (p < eEnd)) { 6319 /* Old edges add new edges and vertex */ 6320 for (r = 0; r < 2; ++r) { 6321 newp = eStartNew + (p - eStart)*2 + r; 6322 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6323 } 6324 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6325 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6326 } else if ((p >= fStart) && (p < fEnd)) { 6327 /* Old faces add new faces and edges */ 6328 for (r = 0; r < 4; ++r) { 6329 newp = fStartNew + (p - fStart)*4 + r; 6330 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6331 } 6332 for (r = 0; r < 3; ++r) { 6333 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 6334 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6335 } 6336 } else if ((p >= cStart) && (p < cEnd)) { 6337 /* Old cells add new cells and interior faces and edges */ 6338 for (r = 0; r < 8; ++r) { 6339 newp = cStartNew + (p - cStart)*8 + r; 6340 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6341 } 6342 for (r = 0; r < 8; ++r) { 6343 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 6344 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6345 } 6346 for (r = 0; r < 1; ++r) { 6347 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 6348 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6349 } 6350 } 6351 break; 6352 case 7: 6353 /* Hybrid Simplicial 3D */ 6354 if ((p >= vStart) && (p < vEnd)) { 6355 /* Interior vertices stay the same */ 6356 newp = vStartNew + (p - vStart); 6357 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6358 } else if ((p >= eStart) && (p < eMax)) { 6359 /* Interior edges add new edges and vertex */ 6360 for (r = 0; r < 2; ++r) { 6361 newp = eStartNew + (p - eStart)*2 + r; 6362 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6363 } 6364 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6365 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6366 } else if ((p >= eMax) && (p < eEnd)) { 6367 /* Hybrid edges stay the same */ 6368 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 6369 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6370 } else if ((p >= fStart) && (p < fMax)) { 6371 /* Interior faces add new faces and edges */ 6372 for (r = 0; r < 4; ++r) { 6373 newp = fStartNew + (p - fStart)*4 + r; 6374 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6375 } 6376 for (r = 0; r < 3; ++r) { 6377 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 6378 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6379 } 6380 } else if ((p >= fMax) && (p < fEnd)) { 6381 /* Hybrid faces add new faces and edges */ 6382 for (r = 0; r < 2; ++r) { 6383 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 6384 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6385 } 6386 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 6387 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6388 } else if ((p >= cStart) && (p < cMax)) { 6389 /* Interior cells add new cells, faces, and edges */ 6390 for (r = 0; r < 8; ++r) { 6391 newp = cStartNew + (p - cStart)*8 + r; 6392 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6393 } 6394 for (r = 0; r < 8; ++r) { 6395 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 6396 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6397 } 6398 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 6399 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6400 } else if ((p >= cMax) && (p < cEnd)) { 6401 /* Hybrid cells add new cells and faces */ 6402 for (r = 0; r < 4; ++r) { 6403 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6404 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6405 } 6406 for (r = 0; r < 3; ++r) { 6407 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 6408 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6409 } 6410 } 6411 break; 6412 case 6: 6413 /* Hex 3D */ 6414 if ((p >= vStart) && (p < vEnd)) { 6415 /* Old vertices stay the same */ 6416 newp = vStartNew + (p - vStart); 6417 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6418 } else if ((p >= eStart) && (p < eEnd)) { 6419 /* Old edges add new edges and vertex */ 6420 for (r = 0; r < 2; ++r) { 6421 newp = eStartNew + (p - eStart)*2 + r; 6422 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6423 } 6424 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6425 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6426 } else if ((p >= fStart) && (p < fEnd)) { 6427 /* Old faces add new faces, edges, and vertex */ 6428 for (r = 0; r < 4; ++r) { 6429 newp = fStartNew + (p - fStart)*4 + r; 6430 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6431 } 6432 for (r = 0; r < 4; ++r) { 6433 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 6434 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6435 } 6436 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 6437 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6438 } else if ((p >= cStart) && (p < cEnd)) { 6439 /* Old cells add new cells, faces, edges, and vertex */ 6440 for (r = 0; r < 8; ++r) { 6441 newp = cStartNew + (p - cStart)*8 + r; 6442 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6443 } 6444 for (r = 0; r < 12; ++r) { 6445 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 6446 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6447 } 6448 for (r = 0; r < 6; ++r) { 6449 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 6450 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6451 } 6452 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 6453 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6454 } 6455 break; 6456 case 8: 6457 /* Hybrid Hex 3D */ 6458 if ((p >= vStart) && (p < vEnd)) { 6459 /* Interior vertices stay the same */ 6460 newp = vStartNew + (p - vStart); 6461 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6462 } else if ((p >= eStart) && (p < eMax)) { 6463 /* Interior edges add new edges and vertex */ 6464 for (r = 0; r < 2; ++r) { 6465 newp = eStartNew + (p - eStart)*2 + r; 6466 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6467 } 6468 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6469 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6470 } else if ((p >= eMax) && (p < eEnd)) { 6471 /* Hybrid edges stay the same */ 6472 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 6473 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6474 } else if ((p >= fStart) && (p < fMax)) { 6475 /* Interior faces add new faces, edges, and vertex */ 6476 for (r = 0; r < 4; ++r) { 6477 newp = fStartNew + (p - fStart)*4 + r; 6478 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6479 } 6480 for (r = 0; r < 4; ++r) { 6481 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 6482 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6483 } 6484 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 6485 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6486 } else if ((p >= fMax) && (p < fEnd)) { 6487 /* Hybrid faces add new faces and edges */ 6488 for (r = 0; r < 2; ++r) { 6489 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 6490 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6491 } 6492 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 6493 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6494 } else if ((p >= cStart) && (p < cMax)) { 6495 /* Interior cells add new cells, faces, edges, and vertex */ 6496 for (r = 0; r < 8; ++r) { 6497 newp = cStartNew + (p - cStart)*8 + r; 6498 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6499 } 6500 for (r = 0; r < 12; ++r) { 6501 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 6502 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6503 } 6504 for (r = 0; r < 6; ++r) { 6505 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 6506 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6507 } 6508 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 6509 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6510 } else if ((p >= cMax) && (p < cEnd)) { 6511 /* Hybrid cells add new cells, faces, and edges */ 6512 for (r = 0; r < 4; ++r) { 6513 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6514 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6515 } 6516 for (r = 0; r < 4; ++r) { 6517 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 6518 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6519 } 6520 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 6521 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6522 } 6523 break; 6524 default: 6525 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6526 } 6527 } 6528 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 6529 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 6530 } 6531 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 6532 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 6533 if (0) { 6534 ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr); 6535 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 6536 ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 6537 } 6538 } 6539 PetscFunctionReturn(0); 6540 } 6541 6542 #undef __FUNCT__ 6543 #define __FUNCT__ "DMPlexRefineUniform_Internal" 6544 /* This will only work for interpolated meshes */ 6545 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 6546 { 6547 DM rdm; 6548 PetscInt *depthSize; 6549 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 6550 PetscErrorCode ierr; 6551 6552 PetscFunctionBegin; 6553 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 6554 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 6555 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 6556 ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr); 6557 /* Calculate number of new points of each depth */ 6558 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6559 ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr); 6560 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 6561 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 6562 /* Step 1: Set chart */ 6563 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 6564 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 6565 /* Step 2: Set cone/support sizes */ 6566 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6567 /* Step 3: Setup refined DM */ 6568 ierr = DMSetUp(rdm);CHKERRQ(ierr); 6569 /* Step 4: Set cones and supports */ 6570 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6571 /* Step 5: Stratify */ 6572 ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 6573 /* Step 6: Set coordinates for vertices */ 6574 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6575 /* Step 7: Create pointSF */ 6576 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6577 /* Step 8: Create labels */ 6578 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6579 ierr = PetscFree(depthSize);CHKERRQ(ierr); 6580 6581 *dmRefined = rdm; 6582 PetscFunctionReturn(0); 6583 } 6584 6585 #undef __FUNCT__ 6586 #define __FUNCT__ "DMPlexSetRefinementUniform" 6587 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 6588 { 6589 DM_Plex *mesh = (DM_Plex*) dm->data; 6590 6591 PetscFunctionBegin; 6592 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6593 mesh->refinementUniform = refinementUniform; 6594 PetscFunctionReturn(0); 6595 } 6596 6597 #undef __FUNCT__ 6598 #define __FUNCT__ "DMPlexGetRefinementUniform" 6599 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 6600 { 6601 DM_Plex *mesh = (DM_Plex*) dm->data; 6602 6603 PetscFunctionBegin; 6604 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6605 PetscValidPointer(refinementUniform, 2); 6606 *refinementUniform = mesh->refinementUniform; 6607 PetscFunctionReturn(0); 6608 } 6609 6610 #undef __FUNCT__ 6611 #define __FUNCT__ "DMPlexSetRefinementLimit" 6612 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 6613 { 6614 DM_Plex *mesh = (DM_Plex*) dm->data; 6615 6616 PetscFunctionBegin; 6617 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6618 mesh->refinementLimit = refinementLimit; 6619 PetscFunctionReturn(0); 6620 } 6621 6622 #undef __FUNCT__ 6623 #define __FUNCT__ "DMPlexGetRefinementLimit" 6624 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 6625 { 6626 DM_Plex *mesh = (DM_Plex*) dm->data; 6627 6628 PetscFunctionBegin; 6629 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6630 PetscValidPointer(refinementLimit, 2); 6631 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 6632 *refinementLimit = mesh->refinementLimit; 6633 PetscFunctionReturn(0); 6634 } 6635 6636 #undef __FUNCT__ 6637 #define __FUNCT__ "DMPlexGetCellRefiner_Internal" 6638 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 6639 { 6640 PetscInt dim, cStart, cEnd, coneSize, cMax; 6641 PetscErrorCode ierr; 6642 6643 PetscFunctionBegin; 6644 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 6645 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6646 if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);} 6647 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 6648 ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 6649 switch (dim) { 6650 case 2: 6651 switch (coneSize) { 6652 case 3: 6653 if (cMax >= 0) *cellRefiner = 3; /* Hybrid */ 6654 else *cellRefiner = 1; /* Triangular */ 6655 break; 6656 case 4: 6657 if (cMax >= 0) *cellRefiner = 4; /* Hybrid */ 6658 else *cellRefiner = 2; /* Quadrilateral */ 6659 break; 6660 default: 6661 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6662 } 6663 break; 6664 case 3: 6665 switch (coneSize) { 6666 case 4: 6667 if (cMax >= 0) *cellRefiner = 7; /* Hybrid */ 6668 else *cellRefiner = 5; /* Tetrahedral */ 6669 break; 6670 case 6: 6671 if (cMax >= 0) *cellRefiner = 8; /* Hybrid */ 6672 else *cellRefiner = 6; /* hexahedral */ 6673 break; 6674 default: 6675 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6676 } 6677 break; 6678 default: 6679 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 6680 } 6681 PetscFunctionReturn(0); 6682 } 6683