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, i; 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)] < 0 ? -1 : 1; 2920 i = GetTriEdgeInverse_Static(ornt[0], r) + 2; 2921 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (o*of < 0 ? 1 : 0); 2922 orntNew[i] = 0; 2923 i = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2; 2924 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 2925 orntNew[i] = 0; 2926 of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1; 2927 i = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2; 2928 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], (r+2)%3)] - fMax)*2 + (o*of < 0 ? 0 : 1); 2929 orntNew[i] = 0; 2930 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 2931 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 2932 #if 1 2933 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); 2934 for (p = 0; p < 2; ++p) { 2935 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); 2936 } 2937 for (p = 2; p < 5; ++p) { 2938 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); 2939 } 2940 #endif 2941 } 2942 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 2943 orntNew[0] = 0; 2944 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 2945 orntNew[1] = 0; 2946 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 2947 orntNew[2] = 0; 2948 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 2949 orntNew[3] = 0; 2950 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 2951 orntNew[4] = 0; 2952 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2953 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2954 #if 1 2955 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); 2956 for (p = 0; p < 2; ++p) { 2957 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); 2958 } 2959 for (p = 2; p < 5; ++p) { 2960 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); 2961 } 2962 #endif 2963 } 2964 /* Split faces have 3 edges and the same cells as the parent */ 2965 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2966 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 2967 for (f = fStart; f < fMax; ++f) { 2968 const PetscInt newp = fStartNew + (f - fStart)*4; 2969 const PetscInt *cone, *ornt, *support; 2970 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 2971 2972 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2973 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2974 /* A triangle */ 2975 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 2976 orntNew[0] = ornt[0]; 2977 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 2978 orntNew[1] = -2; 2979 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 2980 orntNew[2] = ornt[2]; 2981 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2982 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2983 #if 1 2984 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); 2985 for (p = 0; p < 3; ++p) { 2986 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); 2987 } 2988 #endif 2989 /* B triangle */ 2990 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 2991 orntNew[0] = ornt[0]; 2992 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 2993 orntNew[1] = ornt[1]; 2994 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 2995 orntNew[2] = -2; 2996 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2997 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2998 #if 1 2999 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); 3000 for (p = 0; p < 3; ++p) { 3001 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); 3002 } 3003 #endif 3004 /* C triangle */ 3005 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3006 orntNew[0] = -2; 3007 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 3008 orntNew[1] = ornt[1]; 3009 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 3010 orntNew[2] = ornt[2]; 3011 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3012 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3013 #if 1 3014 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); 3015 for (p = 0; p < 3; ++p) { 3016 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); 3017 } 3018 #endif 3019 /* D triangle */ 3020 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 3021 orntNew[0] = 0; 3022 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3023 orntNew[1] = 0; 3024 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 3025 orntNew[2] = 0; 3026 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3027 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3028 #if 1 3029 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); 3030 for (p = 0; p < 3; ++p) { 3031 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); 3032 } 3033 #endif 3034 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3035 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3036 for (r = 0; r < 4; ++r) { 3037 for (s = 0; s < supportSize; ++s) { 3038 PetscInt subf; 3039 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3040 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3041 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3042 for (c = 0; c < coneSize; ++c) { 3043 if (cone[c] == f) break; 3044 } 3045 subf = GetTriSubfaceInverse_Static(ornt[c], r); 3046 if (support[s] < cMax) { 3047 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 3048 } else { 3049 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf); 3050 } 3051 } 3052 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 3053 #if 1 3054 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); 3055 for (p = 0; p < supportSize; ++p) { 3056 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); 3057 } 3058 #endif 3059 } 3060 } 3061 /* Interior cell faces have 3 edges and 2 cells */ 3062 for (c = cStart; c < cMax; ++c) { 3063 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 3064 const PetscInt *cone, *ornt; 3065 PetscInt coneNew[3], orntNew[3]; 3066 PetscInt supportNew[2]; 3067 3068 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3069 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3070 /* Face A: {c, a, d} */ 3071 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 3072 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3073 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 3074 orntNew[1] = ornt[1] < 0 ? -2 : 0; 3075 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2); 3076 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3077 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3078 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3079 #if 1 3080 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3081 for (p = 0; p < 3; ++p) { 3082 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); 3083 } 3084 #endif 3085 supportNew[0] = (c - cStart)*8 + 0; 3086 supportNew[1] = (c - cStart)*8 + 0+4; 3087 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3088 #if 1 3089 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3090 for (p = 0; p < 2; ++p) { 3091 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); 3092 } 3093 #endif 3094 ++newp; 3095 /* Face B: {a, b, e} */ 3096 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 3097 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3098 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0); 3099 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3100 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 3101 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3102 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3103 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3104 #if 1 3105 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); 3106 for (p = 0; p < 3; ++p) { 3107 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); 3108 } 3109 #endif 3110 supportNew[0] = (c - cStart)*8 + 1; 3111 supportNew[1] = (c - cStart)*8 + 1+4; 3112 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3113 #if 1 3114 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3115 for (p = 0; p < 2; ++p) { 3116 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); 3117 } 3118 #endif 3119 ++newp; 3120 /* Face C: {c, f, b} */ 3121 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 3122 orntNew[0] = ornt[2] < 0 ? -2 : 0; 3123 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 3124 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3125 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1); 3126 orntNew[2] = ornt[0] < 0 ? -2 : 0; 3127 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3128 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3129 #if 1 3130 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3131 for (p = 0; p < 3; ++p) { 3132 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); 3133 } 3134 #endif 3135 supportNew[0] = (c - cStart)*8 + 2; 3136 supportNew[1] = (c - cStart)*8 + 2+4; 3137 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3138 #if 1 3139 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3140 for (p = 0; p < 2; ++p) { 3141 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); 3142 } 3143 #endif 3144 ++newp; 3145 /* Face D: {d, e, f} */ 3146 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0); 3147 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3148 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 3149 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3150 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 3151 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3152 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3153 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3154 #if 1 3155 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3156 for (p = 0; p < 3; ++p) { 3157 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); 3158 } 3159 #endif 3160 supportNew[0] = (c - cStart)*8 + 3; 3161 supportNew[1] = (c - cStart)*8 + 3+4; 3162 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3163 #if 1 3164 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3165 for (p = 0; p < 2; ++p) { 3166 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); 3167 } 3168 #endif 3169 ++newp; 3170 /* Face E: {d, f, a} */ 3171 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 3172 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3173 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3174 orntNew[1] = -2; 3175 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 3176 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3177 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3178 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3179 #if 1 3180 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3181 for (p = 0; p < 3; ++p) { 3182 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); 3183 } 3184 #endif 3185 supportNew[0] = (c - cStart)*8 + 0+4; 3186 supportNew[1] = (c - cStart)*8 + 3+4; 3187 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3188 #if 1 3189 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3190 for (p = 0; p < 2; ++p) { 3191 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); 3192 } 3193 #endif 3194 ++newp; 3195 /* Face F: {c, a, f} */ 3196 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 3197 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3198 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3199 orntNew[1] = 0; 3200 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 3201 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3202 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3203 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3204 #if 1 3205 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3206 for (p = 0; p < 3; ++p) { 3207 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); 3208 } 3209 #endif 3210 supportNew[0] = (c - cStart)*8 + 0+4; 3211 supportNew[1] = (c - cStart)*8 + 2+4; 3212 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3213 #if 1 3214 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3215 for (p = 0; p < 2; ++p) { 3216 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); 3217 } 3218 #endif 3219 ++newp; 3220 /* Face G: {e, a, f} */ 3221 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 3222 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3223 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3224 orntNew[1] = 0; 3225 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 3226 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3227 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3228 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3229 #if 1 3230 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3231 for (p = 0; p < 3; ++p) { 3232 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); 3233 } 3234 #endif 3235 supportNew[0] = (c - cStart)*8 + 1+4; 3236 supportNew[1] = (c - cStart)*8 + 3+4; 3237 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3238 #if 1 3239 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3240 for (p = 0; p < 2; ++p) { 3241 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); 3242 } 3243 #endif 3244 ++newp; 3245 /* Face H: {a, b, f} */ 3246 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 3247 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3248 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 3249 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3250 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3251 orntNew[2] = -2; 3252 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3253 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3254 #if 1 3255 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3256 for (p = 0; p < 3; ++p) { 3257 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); 3258 } 3259 #endif 3260 supportNew[0] = (c - cStart)*8 + 1+4; 3261 supportNew[1] = (c - cStart)*8 + 2+4; 3262 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3263 #if 1 3264 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3265 for (p = 0; p < 2; ++p) { 3266 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); 3267 } 3268 #endif 3269 ++newp; 3270 } 3271 /* Hybrid split faces have 4 edges and same cells */ 3272 for (f = fMax; f < fEnd; ++f) { 3273 const PetscInt *cone, *ornt, *support; 3274 PetscInt coneNew[4], orntNew[4]; 3275 PetscInt supportNew[2], size, s, c; 3276 3277 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3278 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3279 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3280 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3281 for (r = 0; r < 2; ++r) { 3282 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 3283 3284 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 3285 orntNew[0] = ornt[0]; 3286 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 3287 orntNew[1] = ornt[1]; 3288 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 3289 orntNew[2+r] = 0; 3290 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3291 orntNew[3-r] = 0; 3292 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3293 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3294 #if 1 3295 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3296 for (p = 0; p < 2; ++p) { 3297 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); 3298 } 3299 for (p = 2; p < 4; ++p) { 3300 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); 3301 } 3302 #endif 3303 for (s = 0; s < size; ++s) { 3304 const PetscInt *coneCell, *orntCell, *fornt; 3305 PetscInt o, of; 3306 3307 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 3308 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 3309 o = orntCell[0] < 0 ? -1 : 1; 3310 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 3311 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 3312 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 3313 of = fornt[c-2] < 0 ? -1 : 1; 3314 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 3315 } 3316 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3317 #if 1 3318 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3319 for (p = 0; p < size; ++p) { 3320 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); 3321 } 3322 #endif 3323 } 3324 } 3325 /* Hybrid cell faces have 4 edges and 2 cells */ 3326 for (c = cMax; c < cEnd; ++c) { 3327 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 3328 const PetscInt *cone, *ornt; 3329 PetscInt coneNew[4], orntNew[4]; 3330 PetscInt supportNew[2]; 3331 3332 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3333 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3334 for (r = 0; r < 3; ++r) { 3335 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3; 3336 orntNew[0] = 0; 3337 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3; 3338 orntNew[1] = 0; 3339 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax); 3340 orntNew[2] = 0; 3341 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r] - fMax); 3342 orntNew[3] = 0; 3343 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 3344 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 3345 #if 1 3346 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); 3347 for (p = 0; p < 2; ++p) { 3348 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); 3349 } 3350 for (p = 2; p < 4; ++p) { 3351 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); 3352 } 3353 #endif 3354 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 3355 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 3356 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 3357 #if 1 3358 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); 3359 for (p = 0; p < 2; ++p) { 3360 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); 3361 } 3362 #endif 3363 } 3364 } 3365 /* Interior split edges have 2 vertices and the same faces as the parent */ 3366 for (e = eStart; e < eMax; ++e) { 3367 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3368 3369 for (r = 0; r < 2; ++r) { 3370 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3371 const PetscInt *cone, *ornt, *support; 3372 PetscInt coneNew[2], coneSize, c, supportSize, s; 3373 3374 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3375 coneNew[0] = vStartNew + (cone[0] - vStart); 3376 coneNew[1] = vStartNew + (cone[1] - vStart); 3377 coneNew[(r+1)%2] = newv; 3378 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3379 #if 1 3380 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3381 for (p = 0; p < 2; ++p) { 3382 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); 3383 } 3384 #endif 3385 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3386 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3387 for (s = 0; s < supportSize; ++s) { 3388 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3389 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3390 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3391 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 3392 if (support[s] < fMax) { 3393 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 3394 } else { 3395 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 3396 } 3397 } 3398 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3399 #if 1 3400 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3401 for (p = 0; p < supportSize; ++p) { 3402 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); 3403 } 3404 #endif 3405 } 3406 } 3407 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 3408 for (f = fStart; f < fMax; ++f) { 3409 const PetscInt *cone, *ornt, *support; 3410 PetscInt coneSize, supportSize, s; 3411 3412 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3413 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3414 for (r = 0; r < 3; ++r) { 3415 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 3416 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 3417 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 3418 -1, -1, 1, 6, 0, 4, 3419 2, 5, 3, 4, -1, -1, 3420 -1, -1, 3, 6, 2, 7}; 3421 3422 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3423 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 3424 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 3425 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3426 #if 1 3427 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3428 for (p = 0; p < 2; ++p) { 3429 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); 3430 } 3431 #endif 3432 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 3433 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 3434 for (s = 0; s < supportSize; ++s) { 3435 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3436 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3437 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3438 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 3439 if (support[s] < cMax) { 3440 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 3441 er = GetTetSomethingInverse_Static(ornt[c], r); 3442 if (er == eint[c]) { 3443 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 3444 } else { 3445 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 3446 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 3447 } 3448 } else { 3449 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3; 3450 } 3451 } 3452 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3453 #if 1 3454 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3455 for (p = 0; p < intFaces; ++p) { 3456 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); 3457 } 3458 #endif 3459 } 3460 } 3461 /* Interior cell edges have 2 vertices and 4 faces */ 3462 for (c = cStart; c < cMax; ++c) { 3463 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3464 const PetscInt *cone, *ornt, *fcone; 3465 PetscInt coneNew[2], supportNew[4], find; 3466 3467 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3468 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3469 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 3470 find = GetTriEdge_Static(ornt[0], 0); 3471 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3472 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 3473 find = GetTriEdge_Static(ornt[2], 1); 3474 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3475 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3476 #if 1 3477 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3478 for (p = 0; p < 2; ++p) { 3479 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); 3480 } 3481 #endif 3482 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3483 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3484 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3485 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3486 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3487 #if 1 3488 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3489 for (p = 0; p < 4; ++p) { 3490 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); 3491 } 3492 #endif 3493 } 3494 /* Hybrid edges have two vertices and the same faces */ 3495 for (e = eMax; e < eEnd; ++e) { 3496 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 3497 const PetscInt *cone, *support, *fcone; 3498 PetscInt coneNew[2], size, fsize, s; 3499 3500 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3501 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3502 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3503 coneNew[0] = vStartNew + (cone[0] - vStart); 3504 coneNew[1] = vStartNew + (cone[1] - vStart); 3505 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3506 #if 1 3507 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3508 for (p = 0; p < 2; ++p) { 3509 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); 3510 } 3511 #endif 3512 for (s = 0; s < size; ++s) { 3513 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 3514 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 3515 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 3516 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 3517 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 3518 } 3519 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3520 #if 1 3521 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3522 for (p = 0; p < size; ++p) { 3523 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); 3524 } 3525 #endif 3526 } 3527 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 3528 for (f = fMax; f < fEnd; ++f) { 3529 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3530 const PetscInt *cone, *support, *ccone, *cornt; 3531 PetscInt coneNew[2], size, csize, s; 3532 3533 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3534 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3535 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3536 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 3537 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 3538 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3539 #if 1 3540 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3541 for (p = 0; p < 2; ++p) { 3542 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); 3543 } 3544 #endif 3545 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 3546 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 3547 for (s = 0; s < size; ++s) { 3548 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 3549 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 3550 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 3551 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 3552 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]); 3553 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2; 3554 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3; 3555 } 3556 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3557 #if 1 3558 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3559 for (p = 0; p < 2+size*2; ++p) { 3560 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); 3561 } 3562 #endif 3563 } 3564 /* Interior vertices have identical supports */ 3565 for (v = vStart; v < vEnd; ++v) { 3566 const PetscInt newp = vStartNew + (v - vStart); 3567 const PetscInt *support, *cone; 3568 PetscInt size, s; 3569 3570 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3571 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3572 for (s = 0; s < size; ++s) { 3573 PetscInt r = 0; 3574 3575 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3576 if (cone[1] == v) r = 1; 3577 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3578 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 3579 } 3580 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3581 #if 1 3582 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3583 for (p = 0; p < size; ++p) { 3584 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); 3585 } 3586 #endif 3587 } 3588 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 3589 for (e = eStart; e < eMax; ++e) { 3590 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3591 const PetscInt *cone, *support; 3592 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 3593 3594 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3595 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3596 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3597 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3598 for (s = 0; s < size; ++s) { 3599 PetscInt r = 0; 3600 3601 if (support[s] < fMax) { 3602 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3603 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3604 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 3605 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 3606 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 3607 faceSize += 2; 3608 } else { 3609 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 3610 ++faceSize; 3611 } 3612 } 3613 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3614 for (s = 0; s < starSize*2; s += 2) { 3615 const PetscInt *cone, *ornt; 3616 PetscInt e01, e23; 3617 3618 if ((star[s] >= cStart) && (star[s] < cMax)) { 3619 /* Check edge 0-1 */ 3620 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3621 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3622 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 3623 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 3624 /* Check edge 2-3 */ 3625 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3626 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3627 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 3628 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 3629 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 3630 } 3631 } 3632 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3633 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3634 #if 1 3635 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3636 for (p = 0; p < 2+faceSize+cellSize; ++p) { 3637 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); 3638 } 3639 #endif 3640 } 3641 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3642 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 3643 break; 3644 case 6: 3645 /* Hex 3D */ 3646 /* 3647 Bottom (viewed from top) Top 3648 1---------2---------2 7---------2---------6 3649 | | | | | | 3650 | B 2 C | | H 2 G | 3651 | | | | | | 3652 3----3----0----1----1 3----3----0----1----1 3653 | | | | | | 3654 | A 0 D | | E 0 F | 3655 | | | | | | 3656 0---------0---------3 4---------0---------5 3657 */ 3658 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 3659 for (c = cStart; c < cEnd; ++c) { 3660 const PetscInt newp = (c - cStart)*8; 3661 const PetscInt *cone, *ornt; 3662 PetscInt coneNew[6], orntNew[6]; 3663 3664 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3665 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3666 /* A hex */ 3667 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 3668 orntNew[0] = ornt[0]; 3669 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3670 orntNew[1] = 0; 3671 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 3672 orntNew[2] = ornt[2]; 3673 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3674 orntNew[3] = 0; 3675 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3676 orntNew[4] = 0; 3677 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 3678 orntNew[5] = ornt[5]; 3679 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3680 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3681 #if 1 3682 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); 3683 for (p = 0; p < 6; ++p) { 3684 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); 3685 } 3686 #endif 3687 /* B hex */ 3688 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 3689 orntNew[0] = ornt[0]; 3690 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3691 orntNew[1] = 0; 3692 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3693 orntNew[2] = -1; 3694 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 3695 orntNew[3] = ornt[3]; 3696 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3697 orntNew[4] = 0; 3698 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 3699 orntNew[5] = ornt[5]; 3700 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3701 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3702 #if 1 3703 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); 3704 for (p = 0; p < 6; ++p) { 3705 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); 3706 } 3707 #endif 3708 /* C hex */ 3709 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 3710 orntNew[0] = ornt[0]; 3711 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3712 orntNew[1] = 0; 3713 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3714 orntNew[2] = -1; 3715 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 3716 orntNew[3] = ornt[3]; 3717 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 3718 orntNew[4] = ornt[4]; 3719 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3720 orntNew[5] = -4; 3721 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3722 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3723 #if 1 3724 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); 3725 for (p = 0; p < 6; ++p) { 3726 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); 3727 } 3728 #endif 3729 /* D hex */ 3730 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 3731 orntNew[0] = ornt[0]; 3732 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3733 orntNew[1] = 0; 3734 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 3735 orntNew[2] = ornt[2]; 3736 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3737 orntNew[3] = 0; 3738 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 3739 orntNew[4] = ornt[4]; 3740 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3741 orntNew[5] = -4; 3742 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3743 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3744 #if 1 3745 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); 3746 for (p = 0; p < 6; ++p) { 3747 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); 3748 } 3749 #endif 3750 /* E hex */ 3751 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3752 orntNew[0] = -4; 3753 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 3754 orntNew[1] = ornt[1]; 3755 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 3756 orntNew[2] = ornt[2]; 3757 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3758 orntNew[3] = 0; 3759 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3760 orntNew[4] = -1; 3761 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 3762 orntNew[5] = ornt[5]; 3763 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3764 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3765 #if 1 3766 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); 3767 for (p = 0; p < 6; ++p) { 3768 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); 3769 } 3770 #endif 3771 /* F hex */ 3772 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3773 orntNew[0] = -4; 3774 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 3775 orntNew[1] = ornt[1]; 3776 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 3777 orntNew[2] = ornt[2]; 3778 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3779 orntNew[3] = -1; 3780 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 3781 orntNew[4] = ornt[4]; 3782 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3783 orntNew[5] = 1; 3784 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3785 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3786 #if 1 3787 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); 3788 for (p = 0; p < 6; ++p) { 3789 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); 3790 } 3791 #endif 3792 /* G hex */ 3793 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3794 orntNew[0] = -4; 3795 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 3796 orntNew[1] = ornt[1]; 3797 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3798 orntNew[2] = 0; 3799 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 3800 orntNew[3] = ornt[3]; 3801 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 3802 orntNew[4] = ornt[4]; 3803 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3804 orntNew[5] = -3; 3805 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3806 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3807 #if 1 3808 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); 3809 for (p = 0; p < 6; ++p) { 3810 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); 3811 } 3812 #endif 3813 /* H hex */ 3814 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3815 orntNew[0] = -4; 3816 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 3817 orntNew[1] = ornt[1]; 3818 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3819 orntNew[2] = -1; 3820 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 3821 orntNew[3] = ornt[3]; 3822 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3823 orntNew[4] = 3; 3824 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 3825 orntNew[5] = ornt[5]; 3826 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3827 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3828 #if 1 3829 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); 3830 for (p = 0; p < 6; ++p) { 3831 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); 3832 } 3833 #endif 3834 } 3835 /* Split faces have 4 edges and the same cells as the parent */ 3836 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3837 ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 3838 for (f = fStart; f < fEnd; ++f) { 3839 for (r = 0; r < 4; ++r) { 3840 /* TODO: This can come from GetFaces_Internal() */ 3841 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}; 3842 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 3843 const PetscInt *cone, *ornt, *support; 3844 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 3845 3846 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3847 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3848 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 3849 orntNew[(r+3)%4] = ornt[(r+3)%4]; 3850 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 3851 orntNew[(r+0)%4] = ornt[r]; 3852 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 3853 orntNew[(r+1)%4] = 0; 3854 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 3855 orntNew[(r+2)%4] = -2; 3856 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3857 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3858 #if 1 3859 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3860 for (p = 0; p < 4; ++p) { 3861 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); 3862 } 3863 #endif 3864 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3865 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3866 for (s = 0; s < supportSize; ++s) { 3867 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3868 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3869 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3870 for (c = 0; c < coneSize; ++c) { 3871 if (cone[c] == f) break; 3872 } 3873 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 3874 } 3875 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3876 #if 1 3877 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3878 for (p = 0; p < supportSize; ++p) { 3879 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); 3880 } 3881 #endif 3882 } 3883 } 3884 /* Interior faces have 4 edges and 2 cells */ 3885 for (c = cStart; c < cEnd; ++c) { 3886 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}; 3887 const PetscInt *cone, *ornt; 3888 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 3889 3890 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3891 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3892 /* A-D face */ 3893 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 3894 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 3895 orntNew[0] = 0; 3896 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3897 orntNew[1] = 0; 3898 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3899 orntNew[2] = -2; 3900 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 3901 orntNew[3] = -2; 3902 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3903 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3904 #if 1 3905 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3906 for (p = 0; p < 4; ++p) { 3907 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); 3908 } 3909 #endif 3910 /* C-D face */ 3911 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 3912 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 3913 orntNew[0] = 0; 3914 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3915 orntNew[1] = 0; 3916 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3917 orntNew[2] = -2; 3918 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 3919 orntNew[3] = -2; 3920 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3921 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3922 #if 1 3923 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3924 for (p = 0; p < 4; ++p) { 3925 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); 3926 } 3927 #endif 3928 /* B-C face */ 3929 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 3930 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 3931 orntNew[0] = -2; 3932 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 3933 orntNew[1] = 0; 3934 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3935 orntNew[2] = 0; 3936 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3937 orntNew[3] = -2; 3938 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3939 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3940 #if 1 3941 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3942 for (p = 0; p < 4; ++p) { 3943 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); 3944 } 3945 #endif 3946 /* A-B face */ 3947 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 3948 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 3949 orntNew[0] = -2; 3950 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 3951 orntNew[1] = 0; 3952 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3953 orntNew[2] = 0; 3954 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3955 orntNew[3] = -2; 3956 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3957 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3958 #if 1 3959 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3960 for (p = 0; p < 4; ++p) { 3961 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); 3962 } 3963 #endif 3964 /* E-F face */ 3965 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 3966 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3967 orntNew[0] = -2; 3968 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 3969 orntNew[1] = -2; 3970 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 3971 orntNew[2] = 0; 3972 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3973 orntNew[3] = 0; 3974 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3975 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3976 #if 1 3977 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3978 for (p = 0; p < 4; ++p) { 3979 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); 3980 } 3981 #endif 3982 /* F-G face */ 3983 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 3984 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3985 orntNew[0] = -2; 3986 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 3987 orntNew[1] = -2; 3988 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 3989 orntNew[2] = 0; 3990 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3991 orntNew[3] = 0; 3992 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3993 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3994 #if 1 3995 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3996 for (p = 0; p < 4; ++p) { 3997 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); 3998 } 3999 #endif 4000 /* G-H face */ 4001 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 4002 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 4003 orntNew[0] = -2; 4004 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 4005 orntNew[1] = 0; 4006 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4007 orntNew[2] = 0; 4008 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4009 orntNew[3] = -2; 4010 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4011 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4012 #if 1 4013 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4014 for (p = 0; p < 4; ++p) { 4015 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); 4016 } 4017 #endif 4018 /* E-H face */ 4019 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 4020 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4021 orntNew[0] = -2; 4022 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 4023 orntNew[1] = -2; 4024 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 4025 orntNew[2] = 0; 4026 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4027 orntNew[3] = 0; 4028 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4029 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4030 #if 1 4031 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4032 for (p = 0; p < 4; ++p) { 4033 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); 4034 } 4035 #endif 4036 /* A-E face */ 4037 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 4038 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 4039 orntNew[0] = 0; 4040 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4041 orntNew[1] = 0; 4042 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4043 orntNew[2] = -2; 4044 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 4045 orntNew[3] = -2; 4046 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4047 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4048 #if 1 4049 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4050 for (p = 0; p < 4; ++p) { 4051 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); 4052 } 4053 #endif 4054 /* D-F face */ 4055 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 4056 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 4057 orntNew[0] = -2; 4058 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 4059 orntNew[1] = 0; 4060 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4061 orntNew[2] = 0; 4062 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4063 orntNew[3] = -2; 4064 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4065 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4066 #if 1 4067 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4068 for (p = 0; p < 4; ++p) { 4069 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); 4070 } 4071 #endif 4072 /* C-G face */ 4073 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 4074 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4075 orntNew[0] = -2; 4076 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 4077 orntNew[1] = -2; 4078 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 4079 orntNew[2] = 0; 4080 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4081 orntNew[3] = 0; 4082 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4083 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4084 #if 1 4085 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4086 for (p = 0; p < 4; ++p) { 4087 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); 4088 } 4089 #endif 4090 /* B-H face */ 4091 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 4092 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4093 orntNew[0] = 0; 4094 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4095 orntNew[1] = -2; 4096 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 4097 orntNew[2] = -2; 4098 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 4099 orntNew[3] = 0; 4100 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4101 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4102 #if 1 4103 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4104 for (p = 0; p < 4; ++p) { 4105 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); 4106 } 4107 #endif 4108 for (r = 0; r < 12; ++r) { 4109 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 4110 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 4111 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 4112 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4113 #if 1 4114 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4115 for (p = 0; p < 2; ++p) { 4116 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); 4117 } 4118 #endif 4119 } 4120 } 4121 /* Split edges have 2 vertices and the same faces as the parent */ 4122 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4123 for (e = eStart; e < eEnd; ++e) { 4124 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4125 4126 for (r = 0; r < 2; ++r) { 4127 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4128 const PetscInt *cone, *ornt, *support; 4129 PetscInt coneNew[2], coneSize, c, supportSize, s; 4130 4131 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4132 coneNew[0] = vStartNew + (cone[0] - vStart); 4133 coneNew[1] = vStartNew + (cone[1] - vStart); 4134 coneNew[(r+1)%2] = newv; 4135 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4136 #if 1 4137 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4138 for (p = 0; p < 2; ++p) { 4139 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); 4140 } 4141 #endif 4142 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4143 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4144 for (s = 0; s < supportSize; ++s) { 4145 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4146 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4147 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4148 for (c = 0; c < coneSize; ++c) { 4149 if (cone[c] == e) break; 4150 } 4151 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 4152 } 4153 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4154 #if 1 4155 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4156 for (p = 0; p < supportSize; ++p) { 4157 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); 4158 } 4159 #endif 4160 } 4161 } 4162 /* Face edges have 2 vertices and 2+cells faces */ 4163 for (f = fStart; f < fEnd; ++f) { 4164 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}; 4165 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 4166 const PetscInt *cone, *coneCell, *orntCell, *support; 4167 PetscInt coneNew[2], coneSize, c, supportSize, s; 4168 4169 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4170 for (r = 0; r < 4; ++r) { 4171 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 4172 4173 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 4174 coneNew[1] = newv; 4175 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4176 #if 1 4177 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4178 for (p = 0; p < 2; ++p) { 4179 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); 4180 } 4181 #endif 4182 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4183 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4184 supportRef[0] = fStartNew + (f - fStart)*4 + r; 4185 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 4186 for (s = 0; s < supportSize; ++s) { 4187 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4188 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4189 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4190 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 4191 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 4192 } 4193 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4194 #if 1 4195 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4196 for (p = 0; p < 2+supportSize; ++p) { 4197 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); 4198 } 4199 #endif 4200 } 4201 } 4202 /* Cell edges have 2 vertices and 4 faces */ 4203 for (c = cStart; c < cEnd; ++c) { 4204 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}; 4205 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 4206 const PetscInt *cone; 4207 PetscInt coneNew[2], supportNew[4]; 4208 4209 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4210 for (r = 0; r < 6; ++r) { 4211 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 4212 4213 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 4214 coneNew[1] = newv; 4215 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4216 #if 1 4217 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4218 for (p = 0; p < 2; ++p) { 4219 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); 4220 } 4221 #endif 4222 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 4223 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4224 #if 1 4225 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4226 for (p = 0; p < 4; ++p) { 4227 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); 4228 } 4229 #endif 4230 } 4231 } 4232 /* Old vertices have identical supports */ 4233 for (v = vStart; v < vEnd; ++v) { 4234 const PetscInt newp = vStartNew + (v - vStart); 4235 const PetscInt *support, *cone; 4236 PetscInt size, s; 4237 4238 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4239 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4240 for (s = 0; s < size; ++s) { 4241 PetscInt r = 0; 4242 4243 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4244 if (cone[1] == v) r = 1; 4245 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4246 } 4247 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4248 #if 1 4249 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4250 for (p = 0; p < size; ++p) { 4251 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); 4252 } 4253 #endif 4254 } 4255 /* Edge vertices have 2 + faces supports */ 4256 for (e = eStart; e < eEnd; ++e) { 4257 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4258 const PetscInt *cone, *support; 4259 PetscInt size, s; 4260 4261 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4262 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4263 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4264 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4265 for (s = 0; s < size; ++s) { 4266 PetscInt r; 4267 4268 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4269 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 4270 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 4271 } 4272 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4273 #if 1 4274 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4275 for (p = 0; p < 2+size; ++p) { 4276 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); 4277 } 4278 #endif 4279 } 4280 /* Face vertices have 4 + cells supports */ 4281 for (f = fStart; f < fEnd; ++f) { 4282 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 4283 const PetscInt *cone, *support; 4284 PetscInt size, s; 4285 4286 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4287 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4288 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 4289 for (s = 0; s < size; ++s) { 4290 PetscInt r; 4291 4292 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4293 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 4294 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 4295 } 4296 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4297 #if 1 4298 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4299 for (p = 0; p < 4+size; ++p) { 4300 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); 4301 } 4302 #endif 4303 } 4304 /* Cell vertices have 6 supports */ 4305 for (c = cStart; c < cEnd; ++c) { 4306 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 4307 PetscInt supportNew[6]; 4308 4309 for (r = 0; r < 6; ++r) { 4310 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 4311 } 4312 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4313 } 4314 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4315 break; 4316 case 8: 4317 /* Hybrid Hex 3D */ 4318 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 4319 /* 4320 Bottom (viewed from top) Top 4321 1---------2---------2 7---------2---------6 4322 | | | | | | 4323 | B 2 C | | H 2 G | 4324 | | | | | | 4325 3----3----0----1----1 3----3----0----1----1 4326 | | | | | | 4327 | A 0 D | | E 0 F | 4328 | | | | | | 4329 0---------0---------3 4---------0---------5 4330 */ 4331 /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 4332 for (c = cStart; c < cMax; ++c) { 4333 const PetscInt newp = (c - cStart)*8; 4334 const PetscInt *cone, *ornt; 4335 PetscInt coneNew[6], orntNew[6]; 4336 4337 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4338 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4339 /* A hex */ 4340 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 4341 orntNew[0] = ornt[0]; 4342 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4343 orntNew[1] = 0; 4344 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 4345 orntNew[2] = ornt[2]; 4346 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4347 orntNew[3] = 0; 4348 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4349 orntNew[4] = 0; 4350 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 4351 orntNew[5] = ornt[5]; 4352 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4353 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4354 #if 1 4355 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); 4356 for (p = 0; p < 6; ++p) { 4357 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); 4358 } 4359 #endif 4360 /* B hex */ 4361 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 4362 orntNew[0] = ornt[0]; 4363 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4364 orntNew[1] = 0; 4365 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4366 orntNew[2] = -1; 4367 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 4368 orntNew[3] = ornt[3]; 4369 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4370 orntNew[4] = 0; 4371 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 4372 orntNew[5] = ornt[5]; 4373 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4374 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4375 #if 1 4376 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); 4377 for (p = 0; p < 6; ++p) { 4378 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); 4379 } 4380 #endif 4381 /* C hex */ 4382 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 4383 orntNew[0] = ornt[0]; 4384 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4385 orntNew[1] = 0; 4386 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4387 orntNew[2] = -1; 4388 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 4389 orntNew[3] = ornt[3]; 4390 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 4391 orntNew[4] = ornt[4]; 4392 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4393 orntNew[5] = -4; 4394 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4395 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4396 #if 1 4397 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); 4398 for (p = 0; p < 6; ++p) { 4399 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); 4400 } 4401 #endif 4402 /* D hex */ 4403 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 4404 orntNew[0] = ornt[0]; 4405 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4406 orntNew[1] = 0; 4407 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 4408 orntNew[2] = ornt[2]; 4409 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4410 orntNew[3] = 0; 4411 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 4412 orntNew[4] = ornt[4]; 4413 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4414 orntNew[5] = -4; 4415 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4416 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4417 #if 1 4418 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); 4419 for (p = 0; p < 6; ++p) { 4420 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); 4421 } 4422 #endif 4423 /* E hex */ 4424 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4425 orntNew[0] = -4; 4426 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 4427 orntNew[1] = ornt[1]; 4428 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 4429 orntNew[2] = ornt[2]; 4430 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4431 orntNew[3] = 0; 4432 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4433 orntNew[4] = -1; 4434 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 4435 orntNew[5] = ornt[5]; 4436 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 4437 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 4438 #if 1 4439 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); 4440 for (p = 0; p < 6; ++p) { 4441 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); 4442 } 4443 #endif 4444 /* F hex */ 4445 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4446 orntNew[0] = -4; 4447 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 4448 orntNew[1] = ornt[1]; 4449 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 4450 orntNew[2] = ornt[2]; 4451 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4452 orntNew[3] = -1; 4453 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 4454 orntNew[4] = ornt[4]; 4455 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4456 orntNew[5] = 1; 4457 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 4458 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 4459 #if 1 4460 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); 4461 for (p = 0; p < 6; ++p) { 4462 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); 4463 } 4464 #endif 4465 /* G hex */ 4466 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4467 orntNew[0] = -4; 4468 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 4469 orntNew[1] = ornt[1]; 4470 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4471 orntNew[2] = 0; 4472 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 4473 orntNew[3] = ornt[3]; 4474 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 4475 orntNew[4] = ornt[4]; 4476 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4477 orntNew[5] = -3; 4478 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 4479 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 4480 #if 1 4481 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); 4482 for (p = 0; p < 6; ++p) { 4483 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); 4484 } 4485 #endif 4486 /* H hex */ 4487 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4488 orntNew[0] = -4; 4489 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 4490 orntNew[1] = ornt[1]; 4491 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4492 orntNew[2] = -1; 4493 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 4494 orntNew[3] = ornt[3]; 4495 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4496 orntNew[4] = 3; 4497 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 4498 orntNew[5] = ornt[5]; 4499 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 4500 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 4501 #if 1 4502 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); 4503 for (p = 0; p < 6; ++p) { 4504 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); 4505 } 4506 #endif 4507 } 4508 /* Hybrid cells have 6 faces: Front, Back, Sides */ 4509 /* 4510 3---------2---------2 4511 | | | 4512 | D 2 C | 4513 | | | 4514 3----3----0----1----1 4515 | | | 4516 | A 0 B | 4517 | | | 4518 0---------0---------1 4519 */ 4520 for (c = cMax; c < cEnd; ++c) { 4521 const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4; 4522 const PetscInt *cone, *ornt, *fornt; 4523 PetscInt coneNew[6], orntNew[6]; 4524 4525 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4526 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4527 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 4528 for (r = 0; r < 4; ++r) { 4529 PetscInt subfA = GetQuadSubface_Static(ornt[0], r); 4530 PetscInt edgeA = GetQuadEdge_Static(ornt[0], r); 4531 PetscInt edgeB = (edgeA+3)%4; 4532 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]); 4533 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA; 4534 orntNew[0] = ornt[0]; 4535 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA; 4536 orntNew[1] = ornt[0]; 4537 coneNew[(r+0)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[edgeA+2] - fMax)*2 + (fornt[edgeA] < 0 ? 1 : 0); 4538 orntNew[(r+0)%4+2] = ornt[edgeA]; 4539 coneNew[(r+1)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA; 4540 orntNew[(r+1)%4+2] = 0; 4541 coneNew[(r+2)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB; 4542 orntNew[(r+2)%4+2] = -2; 4543 coneNew[(r+3)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[edgeB+2] - fMax)*2 + (fornt[edgeB] < 0 ? 0 : 1); 4544 orntNew[(r+3)%4+2] = ornt[edgeB]; 4545 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4546 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4547 #if 1 4548 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); 4549 for (p = 0; p < 2; ++p) { 4550 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); 4551 } 4552 for (p = 2; p < 6; ++p) { 4553 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); 4554 } 4555 #endif 4556 } 4557 } 4558 /* Interior split faces have 4 edges and the same cells as the parent */ 4559 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4560 ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 4561 for (f = fStart; f < fMax; ++f) { 4562 for (r = 0; r < 4; ++r) { 4563 /* TODO: This can come from GetFaces_Internal() */ 4564 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}; 4565 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 4566 const PetscInt *cone, *ornt, *support; 4567 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 4568 4569 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4570 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4571 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 4572 orntNew[(r+3)%4] = ornt[(r+3)%4]; 4573 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 4574 orntNew[(r+0)%4] = ornt[r]; 4575 coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 4576 orntNew[(r+1)%4] = 0; 4577 coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4; 4578 orntNew[(r+2)%4] = -2; 4579 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4580 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4581 #if 1 4582 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4583 for (p = 0; p < 4; ++p) { 4584 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); 4585 } 4586 #endif 4587 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4588 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4589 for (s = 0; s < supportSize; ++s) { 4590 PetscInt subf; 4591 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4592 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4593 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4594 for (c = 0; c < coneSize; ++c) { 4595 if (cone[c] == f) break; 4596 } 4597 subf = GetQuadSubfaceInverse_Static(ornt[c], r); 4598 if (support[s] < cMax) { 4599 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf]; 4600 } else { 4601 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf; 4602 } 4603 } 4604 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4605 #if 1 4606 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4607 for (p = 0; p < supportSize; ++p) { 4608 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); 4609 } 4610 #endif 4611 } 4612 } 4613 /* Interior faces have 4 edges and 2 cells */ 4614 for (c = cStart; c < cMax; ++c) { 4615 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}; 4616 const PetscInt *cone, *ornt; 4617 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 4618 4619 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4620 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4621 /* A-D face */ 4622 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; 4623 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 4624 orntNew[0] = 0; 4625 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4626 orntNew[1] = 0; 4627 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4628 orntNew[2] = -2; 4629 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 4630 orntNew[3] = -2; 4631 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4632 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4633 #if 1 4634 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4635 for (p = 0; p < 4; ++p) { 4636 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); 4637 } 4638 #endif 4639 /* C-D face */ 4640 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; 4641 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 4642 orntNew[0] = 0; 4643 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4644 orntNew[1] = 0; 4645 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4646 orntNew[2] = -2; 4647 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 4648 orntNew[3] = -2; 4649 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4650 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4651 #if 1 4652 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4653 for (p = 0; p < 4; ++p) { 4654 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); 4655 } 4656 #endif 4657 /* B-C face */ 4658 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; 4659 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 4660 orntNew[0] = -2; 4661 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 4662 orntNew[1] = 0; 4663 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4664 orntNew[2] = 0; 4665 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4666 orntNew[3] = -2; 4667 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4668 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4669 #if 1 4670 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4671 for (p = 0; p < 4; ++p) { 4672 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); 4673 } 4674 #endif 4675 /* A-B face */ 4676 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; 4677 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 4678 orntNew[0] = -2; 4679 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 4680 orntNew[1] = 0; 4681 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4682 orntNew[2] = 0; 4683 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4684 orntNew[3] = -2; 4685 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4686 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4687 #if 1 4688 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4689 for (p = 0; p < 4; ++p) { 4690 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); 4691 } 4692 #endif 4693 /* E-F face */ 4694 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; 4695 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4696 orntNew[0] = -2; 4697 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 4698 orntNew[1] = -2; 4699 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 4700 orntNew[2] = 0; 4701 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4702 orntNew[3] = 0; 4703 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4704 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4705 #if 1 4706 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4707 for (p = 0; p < 4; ++p) { 4708 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); 4709 } 4710 #endif 4711 /* F-G face */ 4712 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; 4713 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4714 orntNew[0] = -2; 4715 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 4716 orntNew[1] = -2; 4717 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 4718 orntNew[2] = 0; 4719 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4720 orntNew[3] = 0; 4721 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4722 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4723 #if 1 4724 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4725 for (p = 0; p < 4; ++p) { 4726 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); 4727 } 4728 #endif 4729 /* G-H face */ 4730 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; 4731 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 4732 orntNew[0] = -2; 4733 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 4734 orntNew[1] = 0; 4735 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4736 orntNew[2] = 0; 4737 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4738 orntNew[3] = -2; 4739 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4740 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4741 #if 1 4742 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4743 for (p = 0; p < 4; ++p) { 4744 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); 4745 } 4746 #endif 4747 /* E-H face */ 4748 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; 4749 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4750 orntNew[0] = -2; 4751 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 4752 orntNew[1] = -2; 4753 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 4754 orntNew[2] = 0; 4755 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4756 orntNew[3] = 0; 4757 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4758 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4759 #if 1 4760 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4761 for (p = 0; p < 4; ++p) { 4762 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); 4763 } 4764 #endif 4765 /* A-E face */ 4766 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; 4767 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 4768 orntNew[0] = 0; 4769 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4770 orntNew[1] = 0; 4771 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4772 orntNew[2] = -2; 4773 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 4774 orntNew[3] = -2; 4775 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4776 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4777 #if 1 4778 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4779 for (p = 0; p < 4; ++p) { 4780 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); 4781 } 4782 #endif 4783 /* D-F face */ 4784 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; 4785 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 4786 orntNew[0] = -2; 4787 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 4788 orntNew[1] = 0; 4789 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4790 orntNew[2] = 0; 4791 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4792 orntNew[3] = -2; 4793 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4794 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4795 #if 1 4796 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4797 for (p = 0; p < 4; ++p) { 4798 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); 4799 } 4800 #endif 4801 /* C-G face */ 4802 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; 4803 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4804 orntNew[0] = -2; 4805 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 4806 orntNew[1] = -2; 4807 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 4808 orntNew[2] = 0; 4809 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4810 orntNew[3] = 0; 4811 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4812 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4813 #if 1 4814 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4815 for (p = 0; p < 4; ++p) { 4816 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); 4817 } 4818 #endif 4819 /* B-H face */ 4820 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; 4821 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4822 orntNew[0] = 0; 4823 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4824 orntNew[1] = -2; 4825 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 4826 orntNew[2] = -2; 4827 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 4828 orntNew[3] = 0; 4829 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4830 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4831 #if 1 4832 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4833 for (p = 0; p < 4; ++p) { 4834 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); 4835 } 4836 #endif 4837 for (r = 0; r < 12; ++r) { 4838 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 4839 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 4840 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 4841 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4842 #if 1 4843 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4844 for (p = 0; p < 2; ++p) { 4845 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); 4846 } 4847 #endif 4848 } 4849 } 4850 /* Hybrid split faces have 4 edges and same cells */ 4851 for (f = fMax; f < fEnd; ++f) { 4852 const PetscInt *cone, *ornt, *support; 4853 PetscInt coneNew[4], orntNew[4]; 4854 PetscInt supportNew[2], size, s, c; 4855 4856 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4857 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4858 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4859 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4860 for (r = 0; r < 2; ++r) { 4861 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 4862 4863 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 4864 orntNew[0] = ornt[0]; 4865 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 4866 orntNew[1] = ornt[1]; 4867 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax); 4868 orntNew[2+r] = 0; 4869 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 4870 orntNew[3-r] = 0; 4871 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4872 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4873 #if 1 4874 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 4875 for (p = 0; p < 2; ++p) { 4876 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); 4877 } 4878 for (p = 2; p < 4; ++p) { 4879 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); 4880 } 4881 #endif 4882 for (s = 0; s < size; ++s) { 4883 const PetscInt *coneCell, *orntCell, *fornt; 4884 4885 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4886 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4887 for (c = 2; c < 6; ++c) if (coneCell[c] == f) break; 4888 if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 4889 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 4890 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (fornt[c-2] < 0 ? 1-r : r))%4; 4891 } 4892 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4893 #if 1 4894 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 4895 for (p = 0; p < size; ++p) { 4896 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); 4897 } 4898 #endif 4899 } 4900 } 4901 /* Hybrid cell faces have 4 edges and 2 cells */ 4902 for (c = cMax; c < cEnd; ++c) { 4903 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4; 4904 const PetscInt *cone, *ornt; 4905 PetscInt coneNew[4], orntNew[4]; 4906 PetscInt supportNew[2]; 4907 4908 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4909 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4910 for (r = 0; r < 4; ++r) { 4911 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r); 4912 orntNew[0] = 0; 4913 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r); 4914 orntNew[1] = 0; 4915 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax); 4916 orntNew[2] = 0; 4917 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 4918 orntNew[3] = 0; 4919 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4920 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4921 #if 1 4922 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); 4923 for (p = 0; p < 2; ++p) { 4924 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); 4925 } 4926 for (p = 2; p < 4; ++p) { 4927 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); 4928 } 4929 #endif 4930 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r); 4931 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4); 4932 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 4933 #if 1 4934 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); 4935 for (p = 0; p < 2; ++p) { 4936 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); 4937 } 4938 #endif 4939 } 4940 } 4941 /* Interior split edges have 2 vertices and the same faces as the parent */ 4942 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4943 for (e = eStart; e < eMax; ++e) { 4944 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4945 4946 for (r = 0; r < 2; ++r) { 4947 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4948 const PetscInt *cone, *ornt, *support; 4949 PetscInt coneNew[2], coneSize, c, supportSize, s; 4950 4951 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4952 coneNew[0] = vStartNew + (cone[0] - vStart); 4953 coneNew[1] = vStartNew + (cone[1] - vStart); 4954 coneNew[(r+1)%2] = newv; 4955 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4956 #if 1 4957 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4958 for (p = 0; p < 2; ++p) { 4959 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); 4960 } 4961 #endif 4962 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4963 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4964 for (s = 0; s < supportSize; ++s) { 4965 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4966 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4967 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4968 for (c = 0; c < coneSize; ++c) { 4969 if (cone[c] == e) break; 4970 } 4971 if (support[s] < fMax) { 4972 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4; 4973 } else { 4974 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 4975 } 4976 } 4977 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4978 #if 1 4979 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4980 for (p = 0; p < supportSize; ++p) { 4981 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); 4982 } 4983 #endif 4984 } 4985 } 4986 /* Interior face edges have 2 vertices and 2+cells faces */ 4987 for (f = fStart; f < fMax; ++f) { 4988 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}; 4989 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 4990 const PetscInt *cone, *coneCell, *orntCell, *support; 4991 PetscInt coneNew[2], coneSize, c, supportSize, s; 4992 4993 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4994 for (r = 0; r < 4; ++r) { 4995 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 4996 4997 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 4998 coneNew[1] = newv; 4999 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5000 #if 1 5001 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5002 for (p = 0; p < 2; ++p) { 5003 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); 5004 } 5005 #endif 5006 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5007 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5008 supportRef[0] = fStartNew + (f - fStart)*4 + r; 5009 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 5010 for (s = 0; s < supportSize; ++s) { 5011 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5012 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 5013 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 5014 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 5015 if (support[s] < cMax) { 5016 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 5017 } else { 5018 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + GetQuadEdgeInverse_Static(orntCell[c], r); 5019 } 5020 } 5021 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5022 #if 1 5023 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5024 for (p = 0; p < 2+supportSize; ++p) { 5025 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); 5026 } 5027 #endif 5028 } 5029 } 5030 /* Interior cell edges have 2 vertices and 4 faces */ 5031 for (c = cStart; c < cMax; ++c) { 5032 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}; 5033 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 5034 const PetscInt *cone; 5035 PetscInt coneNew[2], supportNew[4]; 5036 5037 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5038 for (r = 0; r < 6; ++r) { 5039 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 5040 5041 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 5042 coneNew[1] = newv; 5043 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5044 #if 1 5045 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5046 for (p = 0; p < 2; ++p) { 5047 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); 5048 } 5049 #endif 5050 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 5051 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5052 #if 1 5053 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5054 for (p = 0; p < 4; ++p) { 5055 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); 5056 } 5057 #endif 5058 } 5059 } 5060 /* Hybrid edges have two vertices and the same faces */ 5061 for (e = eMax; e < eEnd; ++e) { 5062 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 5063 const PetscInt *cone, *support, *fcone; 5064 PetscInt coneNew[2], size, fsize, s; 5065 5066 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5067 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5068 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5069 coneNew[0] = vStartNew + (cone[0] - vStart); 5070 coneNew[1] = vStartNew + (cone[1] - vStart); 5071 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5072 #if 1 5073 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5074 for (p = 0; p < 2; ++p) { 5075 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); 5076 } 5077 #endif 5078 for (s = 0; s < size; ++s) { 5079 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 5080 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 5081 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 5082 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 5083 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2; 5084 } 5085 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5086 #if 1 5087 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5088 for (p = 0; p < size; ++p) { 5089 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); 5090 } 5091 #endif 5092 } 5093 /* Hybrid face edges have 2 vertices and 2+cells faces */ 5094 for (f = fMax; f < fEnd; ++f) { 5095 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 5096 const PetscInt *cone, *support, *ccone, *cornt; 5097 PetscInt coneNew[2], size, csize, s; 5098 5099 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5100 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5101 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5102 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 5103 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 5104 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5105 #if 1 5106 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5107 for (p = 0; p < 2; ++p) { 5108 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); 5109 } 5110 #endif 5111 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0; 5112 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1; 5113 for (s = 0; s < size; ++s) { 5114 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 5115 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 5116 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 5117 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 5118 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]); 5119 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + GetQuadSubfaceInverse_Static(cornt[0], c-2); 5120 } 5121 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5122 #if 1 5123 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5124 for (p = 0; p < 2+size; ++p) { 5125 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); 5126 } 5127 #endif 5128 } 5129 /* Hybrid cell edges have 2 vertices and 4 faces */ 5130 for (c = cMax; c < cEnd; ++c) { 5131 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 5132 const PetscInt *cone, *support; 5133 PetscInt coneNew[2], size; 5134 5135 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5136 ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr); 5137 ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr); 5138 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 5139 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 5140 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5141 #if 1 5142 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5143 for (p = 0; p < 2; ++p) { 5144 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); 5145 } 5146 #endif 5147 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0; 5148 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1; 5149 supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2; 5150 supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3; 5151 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5152 #if 1 5153 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5154 for (p = 0; p < 4; ++p) { 5155 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); 5156 } 5157 #endif 5158 } 5159 /* Interior vertices have identical supports */ 5160 for (v = vStart; v < vEnd; ++v) { 5161 const PetscInt newp = vStartNew + (v - vStart); 5162 const PetscInt *support, *cone; 5163 PetscInt size, s; 5164 5165 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 5166 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 5167 for (s = 0; s < size; ++s) { 5168 PetscInt r = 0; 5169 5170 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5171 if (cone[1] == v) r = 1; 5172 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 5173 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax); 5174 } 5175 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5176 #if 1 5177 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5178 for (p = 0; p < size; ++p) { 5179 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); 5180 } 5181 #endif 5182 } 5183 /* Interior edge vertices have 2 + faces supports */ 5184 for (e = eStart; e < eMax; ++e) { 5185 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 5186 const PetscInt *cone, *support; 5187 PetscInt size, s; 5188 5189 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5190 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5191 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 5192 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 5193 for (s = 0; s < size; ++s) { 5194 PetscInt r; 5195 5196 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5197 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 5198 if (support[s] < fMax) { 5199 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r; 5200 } else { 5201 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax); 5202 } 5203 } 5204 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5205 #if 1 5206 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5207 for (p = 0; p < 2+size; ++p) { 5208 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); 5209 } 5210 #endif 5211 } 5212 /* Interior face vertices have 4 + cells supports */ 5213 for (f = fStart; f < fMax; ++f) { 5214 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5215 const PetscInt *cone, *support; 5216 PetscInt size, s; 5217 5218 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5219 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5220 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 5221 for (s = 0; s < size; ++s) { 5222 PetscInt r; 5223 5224 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5225 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 5226 if (support[s] < cMax) { 5227 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r; 5228 } else { 5229 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax); 5230 } 5231 } 5232 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5233 #if 1 5234 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5235 for (p = 0; p < 4+size; ++p) { 5236 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); 5237 } 5238 #endif 5239 } 5240 /* Cell vertices have 6 supports */ 5241 for (c = cStart; c < cMax; ++c) { 5242 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 5243 PetscInt supportNew[6]; 5244 5245 for (r = 0; r < 6; ++r) { 5246 supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 5247 } 5248 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5249 } 5250 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5251 break; 5252 default: 5253 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5254 } 5255 PetscFunctionReturn(0); 5256 } 5257 5258 #undef __FUNCT__ 5259 #define __FUNCT__ "CellRefinerSetCoordinates" 5260 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5261 { 5262 PetscSection coordSection, coordSectionNew; 5263 Vec coordinates, coordinatesNew; 5264 PetscScalar *coords, *coordsNew; 5265 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 5266 PetscInt dim, depth, coordSizeNew, cStart, cEnd, cMax, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 5267 PetscErrorCode ierr; 5268 5269 PetscFunctionBegin; 5270 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 5271 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5272 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5273 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5274 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5275 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5276 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 5277 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);} 5278 ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr); 5279 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 5280 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 5281 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 5282 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dim);CHKERRQ(ierr); 5283 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 5284 if (cMax < 0) cMax = cEnd; 5285 if (fMax < 0) fMax = fEnd; 5286 if (eMax < 0) eMax = eEnd; 5287 /* All vertices have the dim coordinates */ 5288 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 5289 ierr = PetscSectionSetDof(coordSectionNew, v, dim);CHKERRQ(ierr); 5290 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dim);CHKERRQ(ierr); 5291 } 5292 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 5293 ierr = DMSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr); 5294 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 5295 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 5296 ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr); 5297 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 5298 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 5299 ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr); 5300 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 5301 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 5302 switch (refiner) { 5303 case 0: break; 5304 case 6: /* Hex 3D */ 5305 case 8: /* Hybrid Hex 3D */ 5306 /* Face vertices have the average of corner coordinates */ 5307 for (f = fStart; f < fMax; ++f) { 5308 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5309 PetscInt *cone = NULL; 5310 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 5311 5312 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5313 for (p = 0; p < closureSize*2; p += 2) { 5314 const PetscInt point = cone[p]; 5315 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 5316 } 5317 for (v = 0; v < coneSize; ++v) { 5318 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 5319 } 5320 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5321 for (d = 0; d < dim; ++d) { 5322 coordsNew[offnew+d] = 0.0; 5323 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 5324 coordsNew[offnew+d] /= coneSize; 5325 } 5326 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5327 } 5328 case 2: /* Hex 2D */ 5329 case 4: /* Hybrid Hex 2D */ 5330 /* Cell vertices have the average of corner coordinates */ 5331 for (c = cStart; c < cMax; ++c) { 5332 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0); 5333 PetscInt *cone = NULL; 5334 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 5335 5336 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5337 for (p = 0; p < closureSize*2; p += 2) { 5338 const PetscInt point = cone[p]; 5339 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 5340 } 5341 for (v = 0; v < coneSize; ++v) { 5342 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 5343 } 5344 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5345 for (d = 0; d < dim; ++d) { 5346 coordsNew[offnew+d] = 0.0; 5347 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 5348 coordsNew[offnew+d] /= coneSize; 5349 } 5350 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5351 } 5352 case 1: /* Simplicial 2D */ 5353 case 3: /* Hybrid Simplicial 2D */ 5354 case 5: /* Simplicial 3D */ 5355 case 7: /* Hybrid Simplicial 3D */ 5356 /* Edge vertices have the average of endpoint coordinates */ 5357 for (e = eStart; e < eMax; ++e) { 5358 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5359 const PetscInt *cone; 5360 PetscInt coneSize, offA, offB, offnew, d; 5361 5362 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 5363 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 5364 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5365 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 5366 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 5367 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5368 for (d = 0; d < dim; ++d) { 5369 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]); 5370 } 5371 } 5372 /* Old vertices have the same coordinates */ 5373 for (v = vStart; v < vEnd; ++v) { 5374 const PetscInt newv = vStartNew + (v - vStart); 5375 PetscInt off, offnew, d; 5376 5377 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 5378 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5379 for (d = 0; d < dim; ++d) { 5380 coordsNew[offnew+d] = coords[off+d]; 5381 } 5382 } 5383 break; 5384 default: 5385 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5386 } 5387 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 5388 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 5389 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 5390 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 5391 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 5392 PetscFunctionReturn(0); 5393 } 5394 5395 #undef __FUNCT__ 5396 #define __FUNCT__ "DMPlexCreateProcessSF" 5397 static PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 5398 { 5399 PetscInt numRoots, numLeaves, l; 5400 const PetscInt *localPoints; 5401 const PetscSFNode *remotePoints; 5402 PetscInt *localPointsNew; 5403 PetscSFNode *remotePointsNew; 5404 PetscInt *ranks, *ranksNew; 5405 PetscErrorCode ierr; 5406 5407 PetscFunctionBegin; 5408 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5409 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 5410 for (l = 0; l < numLeaves; ++l) { 5411 ranks[l] = remotePoints[l].rank; 5412 } 5413 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 5414 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 5415 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 5416 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 5417 for (l = 0; l < numLeaves; ++l) { 5418 ranksNew[l] = ranks[l]; 5419 localPointsNew[l] = l; 5420 remotePointsNew[l].index = 0; 5421 remotePointsNew[l].rank = ranksNew[l]; 5422 } 5423 ierr = PetscFree(ranks);CHKERRQ(ierr); 5424 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr); 5425 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 5426 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 5427 ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 5428 PetscFunctionReturn(0); 5429 } 5430 5431 #undef __FUNCT__ 5432 #define __FUNCT__ "CellRefinerCreateSF" 5433 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5434 { 5435 PetscSF sf, sfNew, sfProcess; 5436 IS processRanks; 5437 MPI_Datatype depthType; 5438 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 5439 const PetscInt *localPoints, *neighbors; 5440 const PetscSFNode *remotePoints; 5441 PetscInt *localPointsNew; 5442 PetscSFNode *remotePointsNew; 5443 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 5444 PetscInt depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 5445 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 5446 PetscErrorCode ierr; 5447 5448 PetscFunctionBegin; 5449 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 5450 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5451 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5452 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5453 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5454 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5455 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 5456 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 5457 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 5458 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 5459 /* Caculate size of new SF */ 5460 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5461 if (numRoots < 0) PetscFunctionReturn(0); 5462 for (l = 0; l < numLeaves; ++l) { 5463 const PetscInt p = localPoints[l]; 5464 5465 switch (refiner) { 5466 case 1: 5467 /* Simplicial 2D */ 5468 if ((p >= vStart) && (p < vEnd)) { 5469 /* Old vertices stay the same */ 5470 ++numLeavesNew; 5471 } else if ((p >= fStart) && (p < fEnd)) { 5472 /* Old faces add new faces and vertex */ 5473 numLeavesNew += 2 + 1; 5474 } else if ((p >= cStart) && (p < cEnd)) { 5475 /* Old cells add new cells and interior faces */ 5476 numLeavesNew += 4 + 3; 5477 } 5478 break; 5479 case 3: 5480 /* Hybrid Simplicial 2D */ 5481 if ((p >= vStart) && (p < vEnd)) { 5482 /* Interior vertices stay the same */ 5483 ++numLeavesNew; 5484 } else if ((p >= fStart) && (p < fMax)) { 5485 /* Interior faces add new faces and vertex */ 5486 numLeavesNew += 2 + 1; 5487 } else if ((p >= fMax) && (p < fEnd)) { 5488 /* Hybrid faces stay the same */ 5489 ++numLeavesNew; 5490 } else if ((p >= cStart) && (p < cMax)) { 5491 /* Interior cells add new cells and interior faces */ 5492 numLeavesNew += 4 + 3; 5493 } else if ((p >= cMax) && (p < cEnd)) { 5494 /* Hybrid cells add new cells and hybrid face */ 5495 numLeavesNew += 2 + 1; 5496 } 5497 break; 5498 case 2: 5499 /* Hex 2D */ 5500 if ((p >= vStart) && (p < vEnd)) { 5501 /* Old vertices stay the same */ 5502 ++numLeavesNew; 5503 } else if ((p >= fStart) && (p < fEnd)) { 5504 /* Old faces add new faces and vertex */ 5505 numLeavesNew += 2 + 1; 5506 } else if ((p >= cStart) && (p < cEnd)) { 5507 /* Old cells add new cells, interior faces, and vertex */ 5508 numLeavesNew += 4 + 4 + 1; 5509 } 5510 break; 5511 case 4: 5512 /* Hybrid Hex 2D */ 5513 if ((p >= vStart) && (p < vEnd)) { 5514 /* Interior vertices stay the same */ 5515 ++numLeavesNew; 5516 } else if ((p >= fStart) && (p < fMax)) { 5517 /* Interior faces add new faces and vertex */ 5518 numLeavesNew += 2 + 1; 5519 } else if ((p >= fMax) && (p < fEnd)) { 5520 /* Hybrid faces stay the same */ 5521 ++numLeavesNew; 5522 } else if ((p >= cStart) && (p < cMax)) { 5523 /* Interior cells add new cells, interior faces, and vertex */ 5524 numLeavesNew += 4 + 4 + 1; 5525 } else if ((p >= cMax) && (p < cEnd)) { 5526 /* Hybrid cells add new cells and hybrid face */ 5527 numLeavesNew += 2 + 1; 5528 } 5529 break; 5530 case 5: 5531 /* Simplicial 3D */ 5532 if ((p >= vStart) && (p < vEnd)) { 5533 /* Old vertices stay the same */ 5534 ++numLeavesNew; 5535 } else if ((p >= eStart) && (p < eEnd)) { 5536 /* Old edges add new edges and vertex */ 5537 numLeavesNew += 2 + 1; 5538 } else if ((p >= fStart) && (p < fEnd)) { 5539 /* Old faces add new faces and face edges */ 5540 numLeavesNew += 4 + 3; 5541 } else if ((p >= cStart) && (p < cEnd)) { 5542 /* Old cells add new cells and interior faces and edges */ 5543 numLeavesNew += 8 + 8 + 1; 5544 } 5545 break; 5546 case 7: 5547 /* Hybrid Simplicial 3D */ 5548 if ((p >= vStart) && (p < vEnd)) { 5549 /* Interior vertices stay the same */ 5550 ++numLeavesNew; 5551 } else if ((p >= eStart) && (p < eMax)) { 5552 /* Interior edges add new edges and vertex */ 5553 numLeavesNew += 2 + 1; 5554 } else if ((p >= eMax) && (p < eEnd)) { 5555 /* Hybrid edges stay the same */ 5556 ++numLeavesNew; 5557 } else if ((p >= fStart) && (p < fMax)) { 5558 /* Interior faces add new faces and edges */ 5559 numLeavesNew += 4 + 3; 5560 } else if ((p >= fMax) && (p < fEnd)) { 5561 /* Hybrid faces add new faces and edges */ 5562 numLeavesNew += 2 + 1; 5563 } else if ((p >= cStart) && (p < cMax)) { 5564 /* Interior cells add new cells, faces, and edges */ 5565 numLeavesNew += 8 + 8 + 1; 5566 } else if ((p >= cMax) && (p < cEnd)) { 5567 /* Hybrid cells add new cells and faces */ 5568 numLeavesNew += 4 + 3; 5569 } 5570 break; 5571 case 6: 5572 /* Hex 3D */ 5573 if ((p >= vStart) && (p < vEnd)) { 5574 /* Old vertices stay the same */ 5575 ++numLeavesNew; 5576 } else if ((p >= eStart) && (p < eEnd)) { 5577 /* Old edges add new edges, and vertex */ 5578 numLeavesNew += 2 + 1; 5579 } else if ((p >= fStart) && (p < fEnd)) { 5580 /* Old faces add new faces, edges, and vertex */ 5581 numLeavesNew += 4 + 4 + 1; 5582 } else if ((p >= cStart) && (p < cEnd)) { 5583 /* Old cells add new cells, faces, edges, and vertex */ 5584 numLeavesNew += 8 + 12 + 6 + 1; 5585 } 5586 break; 5587 case 8: 5588 /* Hybrid Hex 3D */ 5589 if ((p >= vStart) && (p < vEnd)) { 5590 /* Old vertices stay the same */ 5591 ++numLeavesNew; 5592 } else if ((p >= eStart) && (p < eMax)) { 5593 /* Interior edges add new edges, and vertex */ 5594 numLeavesNew += 2 + 1; 5595 } else if ((p >= eMax) && (p < eEnd)) { 5596 /* Hybrid edges stay the same */ 5597 ++numLeavesNew; 5598 } else if ((p >= fStart) && (p < fMax)) { 5599 /* Interior faces add new faces, edges, and vertex */ 5600 numLeavesNew += 4 + 4 + 1; 5601 } else if ((p >= fMax) && (p < fEnd)) { 5602 /* Hybrid faces add new faces and edges */ 5603 numLeavesNew += 2 + 1; 5604 } else if ((p >= cStart) && (p < cMax)) { 5605 /* Interior cells add new cells, faces, edges, and vertex */ 5606 numLeavesNew += 8 + 12 + 6 + 1; 5607 } else if ((p >= cStart) && (p < cEnd)) { 5608 /* Hybrid cells add new cells, faces, and edges */ 5609 numLeavesNew += 4 + 4 + 1; 5610 } 5611 break; 5612 default: 5613 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5614 } 5615 } 5616 /* Communicate depthSizes for each remote rank */ 5617 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 5618 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 5619 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 5620 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 5621 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 5622 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 5623 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5624 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5625 for (n = 0; n < numNeighbors; ++n) { 5626 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 5627 } 5628 depthSizeOld[depth] = cMax; 5629 depthSizeOld[0] = vMax; 5630 depthSizeOld[depth-1] = fMax; 5631 depthSizeOld[1] = eMax; 5632 5633 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5634 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5635 5636 depthSizeOld[depth] = cEnd - cStart; 5637 depthSizeOld[0] = vEnd - vStart; 5638 depthSizeOld[depth-1] = fEnd - fStart; 5639 depthSizeOld[1] = eEnd - eStart; 5640 5641 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5642 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5643 for (n = 0; n < numNeighbors; ++n) { 5644 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 5645 } 5646 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 5647 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 5648 /* Calculate new point SF */ 5649 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 5650 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 5651 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 5652 for (l = 0, m = 0; l < numLeaves; ++l) { 5653 PetscInt p = localPoints[l]; 5654 PetscInt rp = remotePoints[l].index, n; 5655 PetscMPIInt rrank = remotePoints[l].rank; 5656 5657 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 5658 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 5659 switch (refiner) { 5660 case 1: 5661 /* Simplicial 2D */ 5662 if ((p >= vStart) && (p < vEnd)) { 5663 /* Old vertices stay the same */ 5664 localPointsNew[m] = vStartNew + (p - vStart); 5665 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5666 remotePointsNew[m].rank = rrank; 5667 ++m; 5668 } else if ((p >= fStart) && (p < fEnd)) { 5669 /* Old faces add new faces and vertex */ 5670 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5671 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5672 remotePointsNew[m].rank = rrank; 5673 ++m; 5674 for (r = 0; r < 2; ++r, ++m) { 5675 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5676 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5677 remotePointsNew[m].rank = rrank; 5678 } 5679 } else if ((p >= cStart) && (p < cEnd)) { 5680 /* Old cells add new cells and interior faces */ 5681 for (r = 0; r < 4; ++r, ++m) { 5682 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5683 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5684 remotePointsNew[m].rank = rrank; 5685 } 5686 for (r = 0; r < 3; ++r, ++m) { 5687 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 5688 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 5689 remotePointsNew[m].rank = rrank; 5690 } 5691 } 5692 break; 5693 case 2: 5694 /* Hex 2D */ 5695 if ((p >= vStart) && (p < vEnd)) { 5696 /* Old vertices stay the same */ 5697 localPointsNew[m] = vStartNew + (p - vStart); 5698 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5699 remotePointsNew[m].rank = rrank; 5700 ++m; 5701 } else if ((p >= fStart) && (p < fEnd)) { 5702 /* Old faces add new faces and vertex */ 5703 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5704 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5705 remotePointsNew[m].rank = rrank; 5706 ++m; 5707 for (r = 0; r < 2; ++r, ++m) { 5708 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5709 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5710 remotePointsNew[m].rank = rrank; 5711 } 5712 } else if ((p >= cStart) && (p < cEnd)) { 5713 /* Old cells add new cells, interior faces, and vertex */ 5714 for (r = 0; r < 4; ++r, ++m) { 5715 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5716 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5717 remotePointsNew[m].rank = rrank; 5718 } 5719 for (r = 0; r < 4; ++r, ++m) { 5720 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 5721 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r; 5722 remotePointsNew[m].rank = rrank; 5723 } 5724 for (r = 0; r < 1; ++r, ++m) { 5725 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart) + r; 5726 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 5727 remotePointsNew[m].rank = rrank; 5728 } 5729 } 5730 break; 5731 case 3: 5732 /* Hybrid simplicial 2D */ 5733 if ((p >= vStart) && (p < vEnd)) { 5734 /* Old vertices stay the same */ 5735 localPointsNew[m] = vStartNew + (p - vStart); 5736 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5737 remotePointsNew[m].rank = rrank; 5738 ++m; 5739 } else if ((p >= fStart) && (p < fMax)) { 5740 /* Old interior faces add new faces and vertex */ 5741 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5742 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5743 remotePointsNew[m].rank = rrank; 5744 ++m; 5745 for (r = 0; r < 2; ++r, ++m) { 5746 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5747 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5748 remotePointsNew[m].rank = rrank; 5749 } 5750 } else if ((p >= fMax) && (p < fEnd)) { 5751 /* Old hybrid faces stay the same */ 5752 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 5753 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5754 remotePointsNew[m].rank = rrank; 5755 ++m; 5756 } else if ((p >= cStart) && (p < cMax)) { 5757 /* Old interior cells add new cells and interior faces */ 5758 for (r = 0; r < 4; ++r, ++m) { 5759 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5760 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5761 remotePointsNew[m].rank = rrank; 5762 } 5763 for (r = 0; r < 3; ++r, ++m) { 5764 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 5765 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 5766 remotePointsNew[m].rank = rrank; 5767 } 5768 } else if ((p >= cStart) && (p < cMax)) { 5769 /* Old hybrid cells add new cells and hybrid face */ 5770 for (r = 0; r < 2; ++r, ++m) { 5771 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5772 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5773 remotePointsNew[m].rank = rrank; 5774 } 5775 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 5776 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]); 5777 remotePointsNew[m].rank = rrank; 5778 ++m; 5779 } 5780 break; 5781 case 4: 5782 /* Hybrid Hex 2D */ 5783 if ((p >= vStart) && (p < vEnd)) { 5784 /* Old vertices stay the same */ 5785 localPointsNew[m] = vStartNew + (p - vStart); 5786 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5787 remotePointsNew[m].rank = rrank; 5788 ++m; 5789 } else if ((p >= fStart) && (p < fMax)) { 5790 /* Old interior faces add new faces and vertex */ 5791 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5792 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5793 remotePointsNew[m].rank = rrank; 5794 ++m; 5795 for (r = 0; r < 2; ++r, ++m) { 5796 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5797 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5798 remotePointsNew[m].rank = rrank; 5799 } 5800 } else if ((p >= fMax) && (p < fEnd)) { 5801 /* Old hybrid faces stay the same */ 5802 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 5803 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5804 remotePointsNew[m].rank = rrank; 5805 ++m; 5806 } else if ((p >= cStart) && (p < cMax)) { 5807 /* Old interior cells add new cells, interior faces, and vertex */ 5808 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 5809 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 5810 remotePointsNew[m].rank = rrank; 5811 ++m; 5812 for (r = 0; r < 4; ++r, ++m) { 5813 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5814 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5815 remotePointsNew[m].rank = rrank; 5816 } 5817 for (r = 0; r < 4; ++r, ++m) { 5818 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r; 5819 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r; 5820 remotePointsNew[m].rank = rrank; 5821 } 5822 } else if ((p >= cStart) && (p < cMax)) { 5823 /* Old hybrid cells add new cells and hybrid face */ 5824 for (r = 0; r < 2; ++r, ++m) { 5825 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5826 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5827 remotePointsNew[m].rank = rrank; 5828 } 5829 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 5830 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]); 5831 remotePointsNew[m].rank = rrank; 5832 ++m; 5833 } 5834 break; 5835 case 5: 5836 /* Simplicial 3D */ 5837 if ((p >= vStart) && (p < vEnd)) { 5838 /* Old vertices stay the same */ 5839 localPointsNew[m] = vStartNew + (p - vStart); 5840 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5841 remotePointsNew[m].rank = rrank; 5842 ++m; 5843 } else if ((p >= eStart) && (p < eEnd)) { 5844 /* Old edges add new edges and vertex */ 5845 for (r = 0; r < 2; ++r, ++m) { 5846 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5847 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5848 remotePointsNew[m].rank = rrank; 5849 } 5850 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5851 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5852 remotePointsNew[m].rank = rrank; 5853 ++m; 5854 } else if ((p >= fStart) && (p < fEnd)) { 5855 /* Old faces add new faces and face edges */ 5856 for (r = 0; r < 4; ++r, ++m) { 5857 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5858 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5859 remotePointsNew[m].rank = rrank; 5860 } 5861 for (r = 0; r < 3; ++r, ++m) { 5862 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 5863 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*3 + r; 5864 remotePointsNew[m].rank = rrank; 5865 } 5866 } else if ((p >= cStart) && (p < cEnd)) { 5867 /* Old cells add new cells and interior faces and edges */ 5868 for (r = 0; r < 8; ++r, ++m) { 5869 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 5870 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 5871 remotePointsNew[m].rank = rrank; 5872 } 5873 for (r = 0; r < 8; ++r, ++m) { 5874 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 5875 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*8 + r; 5876 remotePointsNew[m].rank = rrank; 5877 } 5878 for (r = 0; r < 1; ++r, ++m) { 5879 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 5880 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*1 + r; 5881 remotePointsNew[m].rank = rrank; 5882 } 5883 } 5884 break; 5885 case 7: 5886 /* Hybrid Simplicial 3D */ 5887 if ((p >= vStart) && (p < vEnd)) { 5888 /* Interior vertices stay the same */ 5889 localPointsNew[m] = vStartNew + (p - vStart); 5890 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5891 remotePointsNew[m].rank = rrank; 5892 ++m; 5893 } else if ((p >= eStart) && (p < eMax)) { 5894 /* Interior edges add new edges and vertex */ 5895 for (r = 0; r < 2; ++r, ++m) { 5896 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5897 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5898 remotePointsNew[m].rank = rrank; 5899 } 5900 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5901 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5902 remotePointsNew[m].rank = rrank; 5903 ++m; 5904 } else if ((p >= eMax) && (p < eEnd)) { 5905 /* Hybrid edges stay the same */ 5906 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 5907 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]); 5908 remotePointsNew[m].rank = rrank; 5909 ++m; 5910 } else if ((p >= fStart) && (p < fMax)) { 5911 /* Interior faces add new faces and edges */ 5912 for (r = 0; r < 4; ++r, ++m) { 5913 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5914 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5915 remotePointsNew[m].rank = rrank; 5916 } 5917 for (r = 0; r < 3; ++r, ++m) { 5918 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 5919 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 5920 remotePointsNew[m].rank = rrank; 5921 } 5922 } else if ((p >= fMax) && (p < fEnd)) { 5923 /* Hybrid faces add new faces and edges */ 5924 for (r = 0; r < 2; ++r, ++m) { 5925 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 5926 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; 5927 remotePointsNew[m].rank = rrank; 5928 } 5929 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 5930 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]); 5931 remotePointsNew[m].rank = rrank; 5932 ++m; 5933 } else if ((p >= cStart) && (p < cMax)) { 5934 /* Interior cells add new cells, faces, and edges */ 5935 for (r = 0; r < 8; ++r, ++m) { 5936 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 5937 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 5938 remotePointsNew[m].rank = rrank; 5939 } 5940 for (r = 0; r < 8; ++r, ++m) { 5941 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 5942 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 5943 remotePointsNew[m].rank = rrank; 5944 } 5945 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + r; 5946 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; 5947 remotePointsNew[m].rank = rrank; 5948 ++m; 5949 } else if ((p >= cMax) && (p < cEnd)) { 5950 /* Hybrid cells add new cells and faces */ 5951 for (r = 0; r < 4; ++r, ++m) { 5952 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 5953 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 5954 remotePointsNew[m].rank = rrank; 5955 } 5956 for (r = 0; r < 3; ++r, ++m) { 5957 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 5958 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; 5959 remotePointsNew[m].rank = rrank; 5960 } 5961 } 5962 break; 5963 case 6: 5964 /* Hex 3D */ 5965 if ((p >= vStart) && (p < vEnd)) { 5966 /* Old vertices stay the same */ 5967 localPointsNew[m] = vStartNew + (p - vStart); 5968 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5969 remotePointsNew[m].rank = rrank; 5970 ++m; 5971 } else if ((p >= eStart) && (p < eEnd)) { 5972 /* Old edges add new edges and vertex */ 5973 for (r = 0; r < 2; ++r, ++m) { 5974 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5975 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5976 remotePointsNew[m].rank = rrank; 5977 } 5978 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5979 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5980 remotePointsNew[m].rank = rrank; 5981 ++m; 5982 } else if ((p >= fStart) && (p < fEnd)) { 5983 /* Old faces add new faces, edges, and vertex */ 5984 for (r = 0; r < 4; ++r, ++m) { 5985 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5986 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5987 remotePointsNew[m].rank = rrank; 5988 } 5989 for (r = 0; r < 4; ++r, ++m) { 5990 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 5991 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*4 + r; 5992 remotePointsNew[m].rank = rrank; 5993 } 5994 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 5995 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]); 5996 remotePointsNew[m].rank = rrank; 5997 ++m; 5998 } else if ((p >= cStart) && (p < cEnd)) { 5999 /* Old cells add new cells, faces, edges, and vertex */ 6000 for (r = 0; r < 8; ++r, ++m) { 6001 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 6002 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 6003 remotePointsNew[m].rank = rrank; 6004 } 6005 for (r = 0; r < 12; ++r, ++m) { 6006 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 6007 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*12 + r; 6008 remotePointsNew[m].rank = rrank; 6009 } 6010 for (r = 0; r < 6; ++r, ++m) { 6011 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 6012 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*6 + r; 6013 remotePointsNew[m].rank = rrank; 6014 } 6015 for (r = 0; r < 1; ++r, ++m) { 6016 localPointsNew[m] = vStartNew + (eEnd - eStart) + (fEnd - fStart) + (p - cStart) + r; 6017 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 6018 remotePointsNew[m].rank = rrank; 6019 } 6020 } 6021 break; 6022 case 8: 6023 /* Hybrid Hex 3D */ 6024 if ((p >= vStart) && (p < vEnd)) { 6025 /* Interior vertices stay the same */ 6026 localPointsNew[m] = vStartNew + (p - vStart); 6027 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 6028 remotePointsNew[m].rank = rrank; 6029 ++m; 6030 } else if ((p >= eStart) && (p < eMax)) { 6031 /* Interior edges add new edges and vertex */ 6032 for (r = 0; r < 2; ++r, ++m) { 6033 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 6034 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 6035 remotePointsNew[m].rank = rrank; 6036 } 6037 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 6038 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 6039 remotePointsNew[m].rank = rrank; 6040 ++m; 6041 } else if ((p >= eMax) && (p < eEnd)) { 6042 /* Hybrid edges stay the same */ 6043 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 6044 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]); 6045 remotePointsNew[m].rank = rrank; 6046 ++m; 6047 } else if ((p >= fStart) && (p < fMax)) { 6048 /* Interior faces add new faces, edges, and vertex */ 6049 for (r = 0; r < 4; ++r, ++m) { 6050 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 6051 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 6052 remotePointsNew[m].rank = rrank; 6053 } 6054 for (r = 0; r < 4; ++r, ++m) { 6055 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 6056 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 6057 remotePointsNew[m].rank = rrank; 6058 } 6059 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 6060 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 6061 remotePointsNew[m].rank = rrank; 6062 ++m; 6063 } else if ((p >= fMax) && (p < fEnd)) { 6064 /* Hybrid faces add new faces and edges */ 6065 for (r = 0; r < 2; ++r, ++m) { 6066 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 6067 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; 6068 remotePointsNew[m].rank = rrank; 6069 } 6070 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax); 6071 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]); 6072 remotePointsNew[m].rank = rrank; 6073 ++m; 6074 } else if ((p >= cStart) && (p < cMax)) { 6075 /* Interior cells add new cells, faces, edges, and vertex */ 6076 for (r = 0; r < 8; ++r, ++m) { 6077 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 6078 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 6079 remotePointsNew[m].rank = rrank; 6080 } 6081 for (r = 0; r < 12; ++r, ++m) { 6082 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 6083 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 6084 remotePointsNew[m].rank = rrank; 6085 } 6086 for (r = 0; r < 6; ++r, ++m) { 6087 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 6088 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; 6089 remotePointsNew[m].rank = rrank; 6090 } 6091 for (r = 0; r < 1; ++r, ++m) { 6092 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 6093 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 6094 remotePointsNew[m].rank = rrank; 6095 } 6096 } else if ((p >= cMax) && (p < cEnd)) { 6097 /* Hybrid cells add new cells, faces, and edges */ 6098 for (r = 0; r < 4; ++r, ++m) { 6099 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6100 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 6101 remotePointsNew[m].rank = rrank; 6102 } 6103 for (r = 0; r < 4; ++r, ++m) { 6104 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 6105 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; 6106 remotePointsNew[m].rank = rrank; 6107 } 6108 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 6109 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]); 6110 remotePointsNew[m].rank = rrank; 6111 ++m; 6112 } 6113 break; 6114 default: 6115 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6116 } 6117 } 6118 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew); 6119 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 6120 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 6121 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 6122 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 6123 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 6124 PetscFunctionReturn(0); 6125 } 6126 6127 #undef __FUNCT__ 6128 #define __FUNCT__ "CellRefinerCreateLabels" 6129 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 6130 { 6131 PetscInt numLabels, l; 6132 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 6133 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 6134 PetscErrorCode ierr; 6135 6136 PetscFunctionBegin; 6137 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6138 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 6139 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6140 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 6141 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6142 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 6143 ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 6144 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 6145 switch (refiner) { 6146 case 0: break; 6147 case 7: 6148 case 8: 6149 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 6150 case 3: 6151 case 4: 6152 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 6153 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 6154 } 6155 for (l = 0; l < numLabels; ++l) { 6156 DMLabel label, labelNew; 6157 const char *lname; 6158 PetscBool isDepth; 6159 IS valueIS; 6160 const PetscInt *values; 6161 PetscInt numValues, val; 6162 6163 ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr); 6164 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 6165 if (isDepth) continue; 6166 ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr); 6167 ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr); 6168 ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 6169 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 6170 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 6171 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 6172 for (val = 0; val < numValues; ++val) { 6173 IS pointIS; 6174 const PetscInt *points; 6175 PetscInt numPoints, n; 6176 6177 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 6178 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 6179 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 6180 for (n = 0; n < numPoints; ++n) { 6181 const PetscInt p = points[n]; 6182 switch (refiner) { 6183 case 1: 6184 /* Simplicial 2D */ 6185 if ((p >= vStart) && (p < vEnd)) { 6186 /* Old vertices stay the same */ 6187 newp = vStartNew + (p - vStart); 6188 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6189 } else if ((p >= fStart) && (p < fEnd)) { 6190 /* Old faces add new faces and vertex */ 6191 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6192 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6193 for (r = 0; r < 2; ++r) { 6194 newp = fStartNew + (p - fStart)*2 + r; 6195 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6196 } 6197 } else if ((p >= cStart) && (p < cEnd)) { 6198 /* Old cells add new cells and interior faces */ 6199 for (r = 0; r < 4; ++r) { 6200 newp = cStartNew + (p - cStart)*4 + r; 6201 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6202 } 6203 for (r = 0; r < 3; ++r) { 6204 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 6205 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6206 } 6207 } 6208 break; 6209 case 2: 6210 /* Hex 2D */ 6211 if ((p >= vStart) && (p < vEnd)) { 6212 /* Old vertices stay the same */ 6213 newp = vStartNew + (p - vStart); 6214 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6215 } else if ((p >= fStart) && (p < fEnd)) { 6216 /* Old faces add new faces and vertex */ 6217 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6218 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6219 for (r = 0; r < 2; ++r) { 6220 newp = fStartNew + (p - fStart)*2 + r; 6221 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6222 } 6223 } else if ((p >= cStart) && (p < cEnd)) { 6224 /* Old cells add new cells and interior faces and vertex */ 6225 for (r = 0; r < 4; ++r) { 6226 newp = cStartNew + (p - cStart)*4 + r; 6227 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6228 } 6229 for (r = 0; r < 4; ++r) { 6230 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 6231 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6232 } 6233 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 6234 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6235 } 6236 break; 6237 case 3: 6238 /* Hybrid simplicial 2D */ 6239 if ((p >= vStart) && (p < vEnd)) { 6240 /* Old vertices stay the same */ 6241 newp = vStartNew + (p - vStart); 6242 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6243 } else if ((p >= fStart) && (p < fMax)) { 6244 /* Old interior faces add new faces and vertex */ 6245 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6246 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6247 for (r = 0; r < 2; ++r) { 6248 newp = fStartNew + (p - fStart)*2 + r; 6249 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6250 } 6251 } else if ((p >= fMax) && (p < fEnd)) { 6252 /* Old hybrid faces stay the same */ 6253 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 6254 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6255 } else if ((p >= cStart) && (p < cMax)) { 6256 /* Old interior cells add new cells and interior faces */ 6257 for (r = 0; r < 4; ++r) { 6258 newp = cStartNew + (p - cStart)*4 + r; 6259 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6260 } 6261 for (r = 0; r < 3; ++r) { 6262 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 6263 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6264 } 6265 } else if ((p >= cMax) && (p < cEnd)) { 6266 /* Old hybrid cells add new cells and hybrid face */ 6267 for (r = 0; r < 2; ++r) { 6268 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 6269 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6270 } 6271 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 6272 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6273 } 6274 break; 6275 case 4: 6276 /* Hybrid Hex 2D */ 6277 if ((p >= vStart) && (p < vEnd)) { 6278 /* Old vertices stay the same */ 6279 newp = vStartNew + (p - vStart); 6280 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6281 } else if ((p >= fStart) && (p < fMax)) { 6282 /* Old interior faces add new faces and vertex */ 6283 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6284 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6285 for (r = 0; r < 2; ++r) { 6286 newp = fStartNew + (p - fStart)*2 + r; 6287 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6288 } 6289 } else if ((p >= fMax) && (p < fEnd)) { 6290 /* Old hybrid faces stay the same */ 6291 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 6292 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6293 } else if ((p >= cStart) && (p < cMax)) { 6294 /* Old interior cells add new cells, interior faces, and vertex */ 6295 for (r = 0; r < 4; ++r) { 6296 newp = cStartNew + (p - cStart)*4 + r; 6297 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6298 } 6299 for (r = 0; r < 4; ++r) { 6300 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 6301 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6302 } 6303 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 6304 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6305 } else if ((p >= cMax) && (p < cEnd)) { 6306 /* Old hybrid cells add new cells and hybrid face */ 6307 for (r = 0; r < 2; ++r) { 6308 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 6309 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6310 } 6311 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 6312 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6313 } 6314 break; 6315 case 5: 6316 /* Simplicial 3D */ 6317 if ((p >= vStart) && (p < vEnd)) { 6318 /* Old vertices stay the same */ 6319 newp = vStartNew + (p - vStart); 6320 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6321 } else if ((p >= eStart) && (p < eEnd)) { 6322 /* Old edges add new edges and vertex */ 6323 for (r = 0; r < 2; ++r) { 6324 newp = eStartNew + (p - eStart)*2 + r; 6325 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6326 } 6327 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6328 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6329 } else if ((p >= fStart) && (p < fEnd)) { 6330 /* Old faces add new faces and edges */ 6331 for (r = 0; r < 4; ++r) { 6332 newp = fStartNew + (p - fStart)*4 + r; 6333 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6334 } 6335 for (r = 0; r < 3; ++r) { 6336 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 6337 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6338 } 6339 } else if ((p >= cStart) && (p < cEnd)) { 6340 /* Old cells add new cells and interior faces and edges */ 6341 for (r = 0; r < 8; ++r) { 6342 newp = cStartNew + (p - cStart)*8 + r; 6343 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6344 } 6345 for (r = 0; r < 8; ++r) { 6346 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 6347 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6348 } 6349 for (r = 0; r < 1; ++r) { 6350 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 6351 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6352 } 6353 } 6354 break; 6355 case 7: 6356 /* Hybrid Simplicial 3D */ 6357 if ((p >= vStart) && (p < vEnd)) { 6358 /* Interior vertices stay the same */ 6359 newp = vStartNew + (p - vStart); 6360 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6361 } else if ((p >= eStart) && (p < eMax)) { 6362 /* Interior edges add new edges and vertex */ 6363 for (r = 0; r < 2; ++r) { 6364 newp = eStartNew + (p - eStart)*2 + r; 6365 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6366 } 6367 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6368 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6369 } else if ((p >= eMax) && (p < eEnd)) { 6370 /* Hybrid edges stay the same */ 6371 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 6372 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6373 } else if ((p >= fStart) && (p < fMax)) { 6374 /* Interior faces add new faces and edges */ 6375 for (r = 0; r < 4; ++r) { 6376 newp = fStartNew + (p - fStart)*4 + r; 6377 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6378 } 6379 for (r = 0; r < 3; ++r) { 6380 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 6381 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6382 } 6383 } else if ((p >= fMax) && (p < fEnd)) { 6384 /* Hybrid faces add new faces and edges */ 6385 for (r = 0; r < 2; ++r) { 6386 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 6387 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6388 } 6389 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 6390 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6391 } else if ((p >= cStart) && (p < cMax)) { 6392 /* Interior cells add new cells, faces, and edges */ 6393 for (r = 0; r < 8; ++r) { 6394 newp = cStartNew + (p - cStart)*8 + r; 6395 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6396 } 6397 for (r = 0; r < 8; ++r) { 6398 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 6399 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6400 } 6401 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 6402 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6403 } else if ((p >= cMax) && (p < cEnd)) { 6404 /* Hybrid cells add new cells and faces */ 6405 for (r = 0; r < 4; ++r) { 6406 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6407 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6408 } 6409 for (r = 0; r < 3; ++r) { 6410 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 6411 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6412 } 6413 } 6414 break; 6415 case 6: 6416 /* Hex 3D */ 6417 if ((p >= vStart) && (p < vEnd)) { 6418 /* Old vertices stay the same */ 6419 newp = vStartNew + (p - vStart); 6420 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6421 } else if ((p >= eStart) && (p < eEnd)) { 6422 /* Old edges add new edges and vertex */ 6423 for (r = 0; r < 2; ++r) { 6424 newp = eStartNew + (p - eStart)*2 + r; 6425 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6426 } 6427 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6428 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6429 } else if ((p >= fStart) && (p < fEnd)) { 6430 /* Old faces add new faces, edges, and vertex */ 6431 for (r = 0; r < 4; ++r) { 6432 newp = fStartNew + (p - fStart)*4 + r; 6433 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6434 } 6435 for (r = 0; r < 4; ++r) { 6436 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 6437 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6438 } 6439 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 6440 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6441 } else if ((p >= cStart) && (p < cEnd)) { 6442 /* Old cells add new cells, faces, edges, and vertex */ 6443 for (r = 0; r < 8; ++r) { 6444 newp = cStartNew + (p - cStart)*8 + r; 6445 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6446 } 6447 for (r = 0; r < 12; ++r) { 6448 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 6449 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6450 } 6451 for (r = 0; r < 6; ++r) { 6452 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 6453 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6454 } 6455 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 6456 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6457 } 6458 break; 6459 case 8: 6460 /* Hybrid Hex 3D */ 6461 if ((p >= vStart) && (p < vEnd)) { 6462 /* Interior vertices stay the same */ 6463 newp = vStartNew + (p - vStart); 6464 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6465 } else if ((p >= eStart) && (p < eMax)) { 6466 /* Interior edges add new edges and vertex */ 6467 for (r = 0; r < 2; ++r) { 6468 newp = eStartNew + (p - eStart)*2 + r; 6469 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6470 } 6471 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6472 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6473 } else if ((p >= eMax) && (p < eEnd)) { 6474 /* Hybrid edges stay the same */ 6475 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 6476 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6477 } else if ((p >= fStart) && (p < fMax)) { 6478 /* Interior faces add new faces, edges, and vertex */ 6479 for (r = 0; r < 4; ++r) { 6480 newp = fStartNew + (p - fStart)*4 + r; 6481 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6482 } 6483 for (r = 0; r < 4; ++r) { 6484 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 6485 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6486 } 6487 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 6488 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6489 } else if ((p >= fMax) && (p < fEnd)) { 6490 /* Hybrid faces add new faces and edges */ 6491 for (r = 0; r < 2; ++r) { 6492 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 6493 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6494 } 6495 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 6496 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6497 } else if ((p >= cStart) && (p < cMax)) { 6498 /* Interior cells add new cells, faces, edges, and vertex */ 6499 for (r = 0; r < 8; ++r) { 6500 newp = cStartNew + (p - cStart)*8 + r; 6501 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6502 } 6503 for (r = 0; r < 12; ++r) { 6504 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 6505 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6506 } 6507 for (r = 0; r < 6; ++r) { 6508 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 6509 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6510 } 6511 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 6512 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6513 } else if ((p >= cMax) && (p < cEnd)) { 6514 /* Hybrid cells add new cells, faces, and edges */ 6515 for (r = 0; r < 4; ++r) { 6516 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6517 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6518 } 6519 for (r = 0; r < 4; ++r) { 6520 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 6521 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6522 } 6523 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 6524 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6525 } 6526 break; 6527 default: 6528 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6529 } 6530 } 6531 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 6532 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 6533 } 6534 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 6535 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 6536 if (0) { 6537 ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr); 6538 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 6539 ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 6540 } 6541 } 6542 PetscFunctionReturn(0); 6543 } 6544 6545 #undef __FUNCT__ 6546 #define __FUNCT__ "DMPlexRefineUniform_Internal" 6547 /* This will only work for interpolated meshes */ 6548 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 6549 { 6550 DM rdm; 6551 PetscInt *depthSize; 6552 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 6553 PetscErrorCode ierr; 6554 6555 PetscFunctionBegin; 6556 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 6557 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 6558 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 6559 ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr); 6560 /* Calculate number of new points of each depth */ 6561 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6562 ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr); 6563 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 6564 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 6565 /* Step 1: Set chart */ 6566 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 6567 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 6568 /* Step 2: Set cone/support sizes */ 6569 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6570 /* Step 3: Setup refined DM */ 6571 ierr = DMSetUp(rdm);CHKERRQ(ierr); 6572 /* Step 4: Set cones and supports */ 6573 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6574 /* Step 5: Stratify */ 6575 ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 6576 /* Step 6: Set coordinates for vertices */ 6577 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6578 /* Step 7: Create pointSF */ 6579 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6580 /* Step 8: Create labels */ 6581 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6582 ierr = PetscFree(depthSize);CHKERRQ(ierr); 6583 6584 *dmRefined = rdm; 6585 PetscFunctionReturn(0); 6586 } 6587 6588 #undef __FUNCT__ 6589 #define __FUNCT__ "DMPlexSetRefinementUniform" 6590 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 6591 { 6592 DM_Plex *mesh = (DM_Plex*) dm->data; 6593 6594 PetscFunctionBegin; 6595 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6596 mesh->refinementUniform = refinementUniform; 6597 PetscFunctionReturn(0); 6598 } 6599 6600 #undef __FUNCT__ 6601 #define __FUNCT__ "DMPlexGetRefinementUniform" 6602 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 6603 { 6604 DM_Plex *mesh = (DM_Plex*) dm->data; 6605 6606 PetscFunctionBegin; 6607 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6608 PetscValidPointer(refinementUniform, 2); 6609 *refinementUniform = mesh->refinementUniform; 6610 PetscFunctionReturn(0); 6611 } 6612 6613 #undef __FUNCT__ 6614 #define __FUNCT__ "DMPlexSetRefinementLimit" 6615 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 6616 { 6617 DM_Plex *mesh = (DM_Plex*) dm->data; 6618 6619 PetscFunctionBegin; 6620 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6621 mesh->refinementLimit = refinementLimit; 6622 PetscFunctionReturn(0); 6623 } 6624 6625 #undef __FUNCT__ 6626 #define __FUNCT__ "DMPlexGetRefinementLimit" 6627 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 6628 { 6629 DM_Plex *mesh = (DM_Plex*) dm->data; 6630 6631 PetscFunctionBegin; 6632 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6633 PetscValidPointer(refinementLimit, 2); 6634 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 6635 *refinementLimit = mesh->refinementLimit; 6636 PetscFunctionReturn(0); 6637 } 6638 6639 #undef __FUNCT__ 6640 #define __FUNCT__ "DMPlexGetCellRefiner_Internal" 6641 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 6642 { 6643 PetscInt dim, cStart, cEnd, coneSize, cMax; 6644 PetscErrorCode ierr; 6645 6646 PetscFunctionBegin; 6647 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 6648 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6649 if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);} 6650 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 6651 ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 6652 switch (dim) { 6653 case 2: 6654 switch (coneSize) { 6655 case 3: 6656 if (cMax >= 0) *cellRefiner = 3; /* Hybrid */ 6657 else *cellRefiner = 1; /* Triangular */ 6658 break; 6659 case 4: 6660 if (cMax >= 0) *cellRefiner = 4; /* Hybrid */ 6661 else *cellRefiner = 2; /* Quadrilateral */ 6662 break; 6663 default: 6664 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6665 } 6666 break; 6667 case 3: 6668 switch (coneSize) { 6669 case 4: 6670 if (cMax >= 0) *cellRefiner = 7; /* Hybrid */ 6671 else *cellRefiner = 5; /* Tetrahedral */ 6672 break; 6673 case 6: 6674 if (cMax >= 0) *cellRefiner = 8; /* Hybrid */ 6675 else *cellRefiner = 6; /* hexahedral */ 6676 break; 6677 default: 6678 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6679 } 6680 break; 6681 default: 6682 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 6683 } 6684 PetscFunctionReturn(0); 6685 } 6686